动态规划——Unidirectional TSP UVA - 116

版权声明: https://blog.csdn.net/a673953508/article/details/83444589

题解:

单向TSP,通过上一步的状态推出下一步的状态,和数字三角形的想法是一样的

紫书上解释挺详细了,这里不用递归来做的话,由前往后推是不行的,因为要字典序最小,如果从前往后推的话是找不出来的(不信可以试一下)

以后弄dp都从后往前推稳定一点

#include <bits/stdc++.h>
using namespace std;

typedef long long ll;
const int inf = 0x3f3f3f3f;

int n,m;
int block[15][110];
int dp[15][110],fro[15][110];

int re_num(int pos, int lr) {
    pos += lr;
    if(pos <= 0) return n;
    if(pos > n) return 1;
    return pos;
}

int main()
{
    //freopen("in.txt","r",stdin);

    while(scanf("%d%d",&n,&m) == 2) {
        memset(fro,0,sizeof(fro));

        for(int i = 1; i <= n; i++) {
            for(int j = 1; j <= m; j++) {
                scanf("%d",&block[i][j]);
            }
        }

        memset(dp,inf,sizeof(dp));
        for(int i = 1; i <= n; i++) dp[i][m] = block[i][m];

        for(int j = m-1; j >= 1; j--) { //每例
            for(int i = 1; i <= n; i++) {   //每行
                for(int k = -1; k <= 1; k++) {
                    int num = re_num(i,k);
                    if(dp[i][j] > dp[num][j+1]+block[i][j] || (dp[i][j]==dp[num][j+1]+block[i][j]&&fro[i][j]>num)) {
                        dp[i][j] = dp[num][j+1]+block[i][j];
                        fro[i][j] = num;
                    }
                }
            }
        }

        int r,minn = inf;
        for(int i = 1; i <= n; i++)
            if(minn > dp[i][1]) {
                r = i;
                minn = dp[i][1];
            }

        int l = 1;
        for(int i = r; i != 0; i = fro[i][l++]) {
            if(l != 1) printf(" ");
            printf("%d",i);
        }
        printf("\n%d\n",minn);
    }

    return 0;
}

猜你喜欢

转载自blog.csdn.net/a673953508/article/details/83444589