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
%d
",start,ans);
107     }
108     return 0;
109 }
View Code
原文地址:https://www.cnblogs.com/zhaopAC/p/5107840.html