UVA - 116 Unidirectional TSP(dp+多段图的最短路)

来源:互联网 发布:湖南大学的校园网域名 编辑:程序博客网 时间:2024/05/20 23:24
题意:
给一个n行m列的整数矩阵,从第一列任何一个位置出发每次往右、右上或右下走一格,最终到达最后一列。要求经过的整数之和最小。整个矩阵是环形的,即第一行的上一行是最后一行,最后一行的下一行是第一行。
输出路径上每行的行号。多解时输出字典序最小的。
解析:

从后往前逆推,dp[i][j]记录,到(i,j)当前整数和最小,再开一个next数组用于保存路径。

#include <cstring>#include <cstdio>#include <algorithm>using namespace std;const int N = 105;const int INF = 0x3f3f3f3f;int grid[N][N];int next[N][N], dp[N][N];int m,n;int main() {while( scanf("%d%d",&n,&m) != EOF) {for(int i = 0; i < n; i++) {for(int j = 0; j < m; j++) {scanf("%d",&grid[i][j]);}}memset(dp,0,sizeof(dp));int ans = INF , first = 0;for(int j = m-1; j >= 0; j--) { //逆推for(int i = 0; i < n; i++) {if(j == m-1) {dp[i][j] = grid[i][j];}else {int rows[3] = {i-1, i, i+1};if(i == 0) { //边界rows[0] = n-1;}if(i == n-1) {rows[2] = 0;}sort(rows,rows+3);dp[i][j] = INF;for(int k = 0; k < 3; k++) { //求当前所花费的最少步数int v = dp[rows[k]][j+1] + grid[i][j];if(v < dp[i][j]) {dp[i][j] = v;next[i][j] = rows[k];}}}if(j == 0 && dp[i][j] < ans) {ans = dp[i][j];first = i;}}}printf("%d",first+1);int i = next[first][0] , j = 1;while( j < m) {printf(" %d",i+1);i = next[i][j];j++;}printf("\n%d\n",ans);}return 0;}


0 0
原创粉丝点击