UVA116Unidirectional TSP(DP+逆推)
http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=18206
题意:M*N的数阵,从左边一列到右边一列走过的数的和的最小。并输出路径和最小值,每一个数能右上,右,右下三种决策,第一行右上是第m行,第m行右下是第1行。
dp【i】【j】存i行j列到最后一列的和的最小,然后逆推,输出路径,就从第一列找最小的dp,然后减去这个数,找右上,右,右下相等的dp,同时行数还得是最小的,思路还是很好想的。做的就是有点麻烦
1 #include <iostream> 2 #include <cstring> 3 #include <algorithm> 4 #include <cstdio> 5 using namespace std; 6 const int INF = 0x3f3f3f3f; 7 int a[20][110],dp[20][110]; 8 int main() 9 { 10 int n,m; 11 while(scanf("%d%d", &m, &n) != EOF) 12 { 13 memset(a, INF, sizeof(a)); 14 for(int i = 1; i <= m; i++) 15 { 16 for(int j = 1; j <= n; j++) 17 { 18 scanf("%d", &a[i][j]); 19 } 20 } 21 22 memset(dp, INF, sizeof(dp)); 23 for(int i = 1; i <= m; i++) 24 dp[i][n] = a[i][n]; 25 26 for(int j = n - 1; j >= 1; j--) 27 { 28 for(int i = 1; i <= m; i++) 29 { 30 if(i == 1) 31 { 32 dp[i][j] = min(dp[i][j], a[i][j] + dp[m][j + 1]); 33 dp[i][j] = min(dp[i][j], a[i][j] + dp[i][j + 1]); 34 dp[i][j] = min(dp[i][j], a[i][j] + dp[i + 1][j + 1]); 35 } 36 else if(i == m) 37 { 38 dp[i][j] = min(dp[i][j], a[i][j] + dp[i - 1][j + 1]); 39 dp[i][j] = min(dp[i][j], a[i][j] + dp[i][j + 1]); 40 dp[i][j] = min(dp[i][j], a[i][j] + dp[1][j + 1]); 41 } 42 else 43 { 44 dp[i][j] = min(dp[i][j], a[i][j] + dp[i - 1][j + 1]); 45 dp[i][j] = min(dp[i][j], a[i][j] + dp[i][j + 1]); 46 dp[i][j] = min(dp[i][j], a[i][j] + dp[i + 1][j + 1]); 47 } 48 } 49 } 50 51 int start; 52 int ans = INF; 53 for(int i = 1; i <= m; i++) 54 { 55 if(ans > dp[i][1]) 56 { 57 ans = dp[i][1]; 58 start = i; 59 } 60 } 61 62 for(int j = 2; j <= n; j++) 63 { 64 printf("%d ",start); 65 int minn = INF; 66 if(start == 1) 67 { 68 if(dp[start][j - 1] - a[start][j - 1] == dp[m][j]) 69 { 70 minn = min(m, minn); 71 } 72 if(dp[start][j - 1] - a[start][j - 1] == dp[start][j]) 73 { 74 minn = min(start, minn); 75 } 76 if(dp[start][j - 1] - a[start][j - 1] == dp[start + 1][j]) 77 { 78 minn = min(start + 1, minn); 79 } 80 start = minn; 81 continue; 82 } 83 else if(start == m) 84 { 85 if(dp[start][j - 1] - a[start][j - 1] == dp[start - 1][j]) 86 minn = min(minn, start - 1); 87 if(dp[start][j - 1] - a[start][j - 1] == dp[start][j]) 88 minn = min(minn, start); 89 if(dp[start][j - 1] - a[start][j - 1] == dp[1][j]) 90 minn = min(minn, 1); 91 start = minn; 92 continue; 93 } 94 else 95 { 96 if(dp[start][j - 1] - a[start][j - 1] == dp[start - 1][j]) 97 minn = min(minn, start - 1); 98 if(dp[start][j - 1] - a[start][j - 1] == dp[start][j]) 99 minn = min(minn, start); 100 if(dp[start][j - 1] - a[start][j - 1] == dp[start + 1][j]) 101 minn = min(minn, start + 1); 102 start = minn; 103 continue; 104 } 105 } 106 printf("%d\n%d\n",start,ans); 107 } 108 return 0; 109 }