uva116 - Unidirectional TSP(简单DP)



 Unidirectional TSP 

Background

Problems that require minimum paths through some domain appear in many different areas of computer science. For example, one of the constraints in VLSI routing problems is minimizing wire length. The Traveling Salesperson Problem (TSP) -- finding whether all the cities in a salesperson's route can be visited exactly once with a specified limit on travel time -- is one of the canonical examples of an NP-complete problem; solutions appear to require an inordinate amount of time to generate, but are simple to check.

This problem deals with finding a minimal path through a grid of points while traveling only from left to right.

The Problem

Given an tex2html_wrap_inline352 matrix of integers, you are to write a program that computes a path of minimal weight. A path starts anywhere in column 1 (the first column) and consists of a sequence of steps terminating in column n (the last column). A step consists of traveling from column i to column i+1 in an adjacent (horizontal or diagonal) row. The first and last rows (rows 1 and m) of a matrix are considered adjacent, i.e., the matrix ``wraps'' so that it represents a horizontal cylinder. Legal steps are illustrated below.

picture25

The weight of a path is the sum of the integers in each of the n cells of the matrix that are visited.

For example, two slightly different tex2html_wrap_inline366 matrices are shown below (the only difference is the numbers in the bottom row).

picture37

The minimal path is illustrated for each matrix. Note that the path for the matrix on the right takes advantage of the adjacency property of the first and last rows.

The Input

The input consists of a sequence of matrix specifications. Each matrix specification consists of the row and column dimensions in that order on a line followed by tex2html_wrap_inline376 integers where m is the row dimension and n is the column dimension. The integers appear in the input in row major order, i.e., the first n integers constitute the first row of the matrix, the second n integers constitute the second row and so on. The integers on a line will be separated from other integers by one or more spaces. Note: integers are not restricted to being positive. There will be one or more matrix specifications in an input file. Input is terminated by end-of-file.

For each specification the number of rows will be between 1 and 10 inclusive; the number of columns will be between 1 and 100 inclusive. No path's weight will exceed integer values representable using 30 bits.

The Output

Two lines should be output for each matrix specification in the input file, the first line represents a minimal-weight path, and the second line is the cost of a minimal path. The path consists of a sequence of nintegers (separated by one or more spaces) representing the rows that constitute the minimal path. If there is more than one path of minimal weight the path that is lexicographically smallest should be output.

Sample Input

5 6
3 4 1 2 8 6
6 1 8 2 7 4
5 9 3 9 9 5
8 4 1 3 2 6
3 7 2 8 6 4
5 6
3 4 1 2 8 6
6 1 8 2 7 4
5 9 3 9 9 5
8 4 1 3 2 6
3 7 2 1 2 3
2 2
9 10 9 10

Sample Output

1 2 3 4 4 5
16
1 2 1 5 4 5
11
1 1
19

思路:简单的递推DP。dp[x][y]=dp[能走][y+1];

很坑人的是字典序最小,没说清是从后往前的字典序,WA了。

#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
const int mm=110;
const int oo=(1<<30)+9;
const int dy[]={-1,0,1};///up,he,down
///字典序最小居然是倒过来的坑爹啊。
int g[mm][mm];
int dp[mm][mm];
int p[mm][mm];
/**
void print(int x,int ce)
{
  if(ce)print(p[x][ce],ce-1);
  else {printf("%d",x+1);return;}
  printf(" %d",x+1);
}*/
int main()
{ ///cout<<oo<<endl;
  int n,m;
  while(~scanf("%d%d",&n,&m))
  {
    for(int i=0;i<n;++i)
      for(int j=0;j<m;++j)
      {scanf("%d",&g[i][j]);dp[i][j]=oo;p[i][j]=oo;}
      for(int i=0;i<n;++i)
        dp[i][m-1]=g[i][m-1];
        int z;
      int ans=0;
      for(int i=m-2;i>=0;--i)///col
        for(int j=0;j<n;++j)///row
      {
        for(int k=0;k<3;++k)
        {
          z=(j+dy[k]+n)%n;
          if(dp[j][i]>dp[z][i+1]+g[j][i])
          {
            dp[j][i]=dp[z][i+1]+g[j][i];
            p[j][i]=z;
          }
          else if(dp[j][i]==dp[z][i+1]+g[j][i]&&z<p[j][i])
            p[j][i]=z;

        }
      }
      int zk;
      for(int i=0;i<n;++i)
       if(dp[i][0]<dp[ans][0])ans=i;
       else if(dp[i][0]==dp[ans][0]&&ans>i)ans=i;
    zk=ans;
    printf("%d",ans+1);ans=p[ans][0];
    for(int i=0;i<m-1;++i,ans=p[ans][i])
      printf(" %d",ans+1);
    printf("\n%d\n",dp[zk][0]);
  }
}

<think> 嗯,用户这次的问题是关于"transport unidirectional in IT field",结合了之前讨论的"transport"概念。看来用户正在研究网络通信相关的技术方向。 从用户之前的提问习惯看,ta似乎是个技术人员,可能正在搭建某个需要单向传输的系统。这次提问提到"unidirectional",说明关注点从通用传输转向了特定传输模式。用户引用的三段材料里,[1]提到分块传输的尾部字段,[2]是编程基础要求,[3]讲协议转换网关,这些虽然不直接相关,但说明用户可能在处理底层通信问题。 需要特别注意用户要求结合"transport"和"unidirectional"两个关键词。在IT领域,单向传输主要有几个典型场景: 首先是流媒体传输,比如HLS协议中服务器持续向客户端推送数据流;其次是监控系统,像安防摄像头只发送不接收的数据流;还有金融市场的行情推送服务,这些都需要可靠的单向传输机制。 用户可能实际想了解的是协议层实现单向传输的技术方案。考虑到ta之前关注过协议转换(引用[3]),或许正在集成不同协议的设备。单向传输常用UDP而不是TCP,因为不需要握手和确认。不过引用[1]提到的分块传输机制(Trailer头部)属于HTTP协议范畴,这和单向传输关系不大。 准备在回复时重点解释三类单向传输应用场景,并对比关键协议特征。要强调单向传输虽然简单但存在丢包风险的特殊性,这个技术点用户可能会忽略。最后生成的三个延伸问题要覆盖协议选择、应用实例和错误处理这些实用角度。 </think> 在IT领域,"transport unidirectional"(单向传输)指数据仅沿单一方向流动的通信模式,常见于以下场景: ### 一、核心概念与技术实现 1. **单向传输协议** 使用无连接协议(如UDP)实现单向数据流,无需接收方确认: $$ \text{发送端} \xrightarrow{\text{数据流}} \text{接收端} $$ 典型案例:传感器数据上报、监控视频流传输[^3] 2. **传输层特性** - **无反向信道**:接收端无法通过原路径反馈(如卫星广播) - **头部控制**:通过特定头部字段声明传输模式(如HTTP Trailer字段声明分块传输特性[^1]) 3. **协议转换架构** 工业场景中通过网关实现协议转换,保持单向传输特性: ```mermaid graph LR 设备[传感器] -->|Modbus| 网关 -->|MQTT| 云平台 ``` 网关仅转发数据,不建立双向会话[^3] ### 二、典型应用场景 | **场景** | **技术实现** | **优势** | |-------------------|----------------------------------|------------------------| | 媒体直播 | RTP over UDP | 低延迟,抗丢包 | | 日志收集 | Syslog协议 | 轻量级,高吞吐量 | | 工业遥测 | Modbus RTU→MQTT网关转换[^3] | 兼容遗留设备 | ### 三、关键技术挑战 1. **数据完整性保障** 通过前向纠错(FEC)或应用层重传机制补偿丢包,例如: $$ \text{FEC} = \bigoplus_{i=1}^{n} D_i \quad (D_i \in \text{数据块}) $$ 2. **传输效率优化** 采用分块传输编码(Chunked Transfer Encoding),通过Trailer字段传递校验信息[^1]: ``` HTTP/1.1 200 OK Transfer-Encoding: chunked Trailer: Content-MD5 ``` ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值