UVA 116 Unidirectional TSP (多阶段决策问题,DP解决)

来源:互联网 发布:虾米音乐解绑淘宝 编辑:程序博客网 时间:2024/06/05 04:58

紫书上的例题,我们令dp【i】【j】为从表格i,j点开始到最后一列的最小花费。由于还需要输出字典序,所以每一个点我们都要得到它能到下一列哪三行,对于第0行和第n-1行特殊处理,然后将这三行排序,从最小的开始检验,如果符合条件则更新,这样就可以处理相等的情况,并且字典序是最小的。

代码如下:

#include<iostream>#include<cstdio>#include<algorithm>#include<cstring>#include<vector>#include<string>#include<set>#include<map>#include<stack>#include<queue>using namespace std;#define eps 1e-7const int maxn = 105;const int maxm = 10005;const int INF = 0x3f3f3f3f;int n, m;int dp[maxn][maxn], nx[maxn][maxn], G[maxn][maxn];int main() {#ifndef ONLINE_JUDGE    freopen("in.txt", "r", stdin);#endif // ONLINE_JUDGE    while(scanf("%d%d", &n, &m) != EOF) {        for(int i = 0; i < n; i++) {            for(int j = 0; j < m; j++) {                scanf("%d", &G[i][j]);            }        }        for(int i = 0; i < n; i++) {            dp[i][m - 1] = G[i][m - 1];        }        for(int j = m - 2; j >= 0; j--) {            for(int i = 0; i < n; i++) {                dp[i][j] = INF;                int row[3] = {i - 1, i, i + 1};                if(i == 0)                    row[0] = n - 1;                if(i == n - 1)                    row[2] = 0;                sort(row, row + 3);                for(int k = 0; k < 3; k++) {                    int d = dp[row[k]][j + 1] + G[i][j];                    if(dp[i][j] > d) {                        dp[i][j] = d;                        nx[i][j] = row[k];                    }                }            }        }        int Min = INF, key;        for(int i = 0; i < n; i++) {            if(dp[i][0] < Min) {                Min = dp[i][0];                key = i;            }        }        for(int i = 0; i < m; i++) {            printf("%d%c", key + 1, i == m - 1 ? '\n' : ' ');            key = nx[key][i];        }        printf("%d\n", Min);    }    return 0;}