(UVA - 116)Unidirectional TSP(DP,多段图的最短路问题)
2017-08-14 16:50
435 查看
链接 : https://vjudge.net/problem/UVA-116
题意:给定m行n列(m<=10,n<=100)的整数矩阵,从第一列的任何一个位置出发每次往右或右上或右下走一格,最终到达最后一列。要求经过的整数之和最小。整个矩阵是环形的,即 第一行的上一行是最后一行,最后一行 的下一行是第一行。输出路径上的每列的行号。多解时输出字典序最小的。
分析:题目是紫书上的,P270. LRJ大神把这个分在 多阶段决策中的多段图的最短路问题中。
因为在本题中,每个阶段就是每一列,每个阶段都有三种决策:直行,右上,右下。
下面是我的理解,在本题中,因为终态是 最后一列,初态是 第一列。
DP做法,n,m的范围不大,设dp[i][j]: 从格子(i,j)出发到 最后一列的 最小整数和。 这种假设方法可以理解为最后一列为初态, 那么循环采用逆推的方法枚举列。
/* 若把dp[i][j] 设为: 从 第一列出发 到 最后一列的最小整数和,那么就顺推 枚举*/
题目读起来 很长,感觉啰嗦,有点迷糊,但是抓住题目的关键点: 起始在第一列的任意位置,矩阵是环形的,终态在最后一列,要求最小整数和, 那么是最短路问题,结合数据范围,可以采用DP,要求输出行号(字典序顺序)。用数组记录行号 感觉还是有迹可循,但是这还是清楚了之火才这样觉得。。
题意:给定m行n列(m<=10,n<=100)的整数矩阵,从第一列的任何一个位置出发每次往右或右上或右下走一格,最终到达最后一列。要求经过的整数之和最小。整个矩阵是环形的,即 第一行的上一行是最后一行,最后一行 的下一行是第一行。输出路径上的每列的行号。多解时输出字典序最小的。
分析:题目是紫书上的,P270. LRJ大神把这个分在 多阶段决策中的多段图的最短路问题中。
因为在本题中,每个阶段就是每一列,每个阶段都有三种决策:直行,右上,右下。
下面是我的理解,在本题中,因为终态是 最后一列,初态是 第一列。
DP做法,n,m的范围不大,设dp[i][j]: 从格子(i,j)出发到 最后一列的 最小整数和。 这种假设方法可以理解为最后一列为初态, 那么循环采用逆推的方法枚举列。
/* 若把dp[i][j] 设为: 从 第一列出发 到 最后一列的最小整数和,那么就顺推 枚举*/
#include<cstdio> #include<cstring> #include<algorithm> using namespace std; const int N=105; const int INF=0x3f3f3f3f; int a ,dp ; int n,m,ne ; void solve() { int first=0; for(int j=n-1; j>=0; j--)///逆推 枚举列 { for(int i=0; i<m; i++)///枚举行 { if(j==n-1) dp[i][j]=a[i][j];///边界: 到达最后一列 else { dp[i][j]=INF;///初始时 是一个不可能达到的值 int rows[]= {i,i-1,i+1};///三种决策 if(i==0) rows[1]=m-1;/// 第1行上面是最后一行 if(i==m-1) rows[2]=0;/// 最后一行下面是第一行, 符合题中 矩阵是环的规则 sort(rows,rows+3); ///对rows 重新排序,找到字典序最小 for(int k=0; k<3; k++)///通过对三种决策的试探,找到最小的那一个 { int val=a[i][j]+dp[rows[k]][j+1]; if(dp[i][j]>val)///当前状态比下一个状态的 整数和要大 { dp[i][j]=val; ne[i][j]=rows[k]; } } } if(j==0&&dp[i][j]<dp[first][j])///第一列 first=i;///first记录第一列的行号 } } printf("%d",first+1); int j=1; for(int i=ne[first][0]; j<n; i=ne[i][j],j++) ///ne记录行号,此处实现类似链表,因为循环中rows的处理,此处的输出一定是字典序最小(最小整数和相等的情况下) printf(" %d",i+1); printf("\n%d\n",dp[first][0]);////dp[first][0]就是题目要求的最小整数和 } int main() { while(~scanf("%d%d",&m,&n)) { for(int i=0; i<m; i++) for(int j=0; j<n; j++) scanf("%d",&a[i][j]); solve(); } return 0; }
题目读起来 很长,感觉啰嗦,有点迷糊,但是抓住题目的关键点: 起始在第一列的任意位置,矩阵是环形的,终态在最后一列,要求最小整数和, 那么是最短路问题,结合数据范围,可以采用DP,要求输出行号(字典序顺序)。用数组记录行号 感觉还是有迹可循,但是这还是清楚了之火才这样觉得。。
相关文章推荐
- uva116 - Unidirectional TSP(简单DP)
- UVa 116:Unidirectional TSP(DP)
- UVa 116 - Unidirectional TSP(DP)
- UVA 116 Unidirectional TSP——dp
- UVa 116 Unidirectional TSP (多段图的最短路 DP)
- 【解题报告】uva116_Unidirectional TSP(单向TSP, dp)
- 紫书动规 例题9-4 UVA - 116 Unidirectional TSP 多段图的最短路 dp
- uva 116 Unidirectional TSP(dp-递归版)
- uva 116 Unidirectional TSP 单向TSP 问题,经典dP(路径输出注意规划方向)
- UVa 116 Unidirectional TSP(简单旅行商DP)
- UVa116 Unidirectional TSP(DP)
- 例题9-4 UVa116 Unidirectional TSP(DP:多段图的最短路)
- Uva--116 Unidirectional TSP(dp)
- UVa 116 Unidirectional TSP(DP)
- dp uva-116-Unidirectional TSP
- UVA 116 Unidirectional TSP(dp)
- UVa 116 Unidirectional TSP(DP)
- uva 116 Unidirectional TSP (dp)
- UVa 116 - Unidirectional TSP(DP)
- uva 116 Unidirectional TSP (dp)