/*----UVa1347 单向TSP 用d(i,j)表示从格子(i,j)出发到最后一列的最小开销 则在(i,j)处有三种决策,d(i,j)转移到d(i-1,j+1),d(i,j+1),d(i+1,j+1),还需要一个数组来记录每一步决策过程 */ #define _CRT_SECURE_NO_DEPRECATE #include<iostream> #include<vector> #include<string.h> #include<math.h> #include<algorithm> #define INF 0x3f3f3f3f using namespace std; const int maxn = 100+10; int a[maxn][maxn], dp[maxn][maxn],c[maxn][maxn]; int n, m; void print(int i, int j){ if (j < m){ printf("%d", i+1); printf(j == m - 1 ? " " : " "); print(c[i][j], j + 1); } } int main(){ int i, j,k; while (~scanf("%d%d", &n, &m)){ for (i = 0; i < n; i++) for (j = 0; j < m; j++) scanf("%d", &a[i][j]); for (j = m - 1; j >= 0; j--) for (i = 0; i < n; i++){ if (j == m - 1) dp[i][j] = a[i][j]; //边界条件 else{ if (i == 0)k = n- 1; else k = i - 1; dp[i][j] = dp[k][j + 1] + a[i][j]; c[i][j] = k; if (dp[i][j] == dp[i][j + 1] + a[i][j] && i<c[i][j]) c[i][j] = i; if (dp[i][j]>dp[i][j + 1] + a[i][j]){ dp[i][j] = dp[i][j + 1] + a[i][j]; c[i][j] = i; } if (i == n - 1) k = 0; else k = i + 1; if (dp[i][j] == dp[k][j + 1] + a[i][j] && k<c[i][j]) c[i][j] = k; if (dp[i][j]>dp[k][j + 1] + a[i][j]){ dp[i][j] = dp[k][j + 1] + a[i][j]; c[i][j] = k; } } } j = 0; for (i = 1; i < n; i++){ if (dp[i][0]<dp[j][0]) j = i; } print(j, 0); printf("%d ", dp[j][0]); } return 0; }