• UVA 116_ Unidirectional TSP


    题意:

    给定整数矩阵,从第一列的任何一个位置出发,每次可以向右、右上、右下走一个格,将最后一行和第一行看成是邻接的,最终到达最后一列,路径长度为所经过格中的整数之和,求最小路径,答案不唯一,输出字典序最小的路径。

    分析:

    数组dp[i][j]记录从第i行第j列出发,到达最后一列的最小路径长度

    • 每个阶段都有三种决策,向右/右上/右下【注意最后一行和第一行的情况
    • 字典序最小,每次都先选择字典序较小的决策
    • 打印路径,记录下一个位置

    代码:

    #include<iostream>
    #include<cmath>
    #include<cstdio>
    #include<algorithm>
    using namespace std;
    const int maxn = 100,  INF=0x3fffffff;
    int c[maxn][maxn], dp[maxn][maxn], s[maxn][maxn];
    int main (void)
    {
        int m ,n;
        while(cin>>n>>m){//n行m列
        for(int i = 0; i < n; i++){
            for(int j = 0; j < m; j++){
                cin>>c[i][j];
                dp[i][j] = INF;
            }
        }
        for(int i = m -1; i >= 0; i--){//j行i列
            for(int j = 0; j < n; j++){
                if(i == m - 1) {dp[j][i] = c[j][i];continue;}
                int r[3]={j, j + 1, j - 1};
                if(j + 1==n) r[1] = 0;
                if(j - 1==-1) r[2] = n-1;
                sort(r, r+3);
                for(int k = 0; k < 3; k++){
                    int d = dp[r[k]][i+1] + c[j][i];
                    if(d<dp[j][i]){
                           dp[j][i] = d ;
                            s[j][i] = r[k];
                        }
                    }
                }
            }
        int ans = INF, t = 0;
        for(int i = 0 ; i < n; i++){
            if(dp[i][0]<ans){
                ans = dp[i][0];
                t = i;
            }
        }
        cout<<t+1;
        for(int i = 0; i < m - 1; i++){
              t = s[t][i];
             cout<<' '<<t+1;
    
        }
            cout<<endl<<ans<<endl;
        }
    }
    
  • 相关阅读:
    【算法笔记】B1007 素数对猜想
    【算法笔记】B1006 换个格式输出整数
    【算法笔记】B1005 继续(3n+1)猜想+sort()用法
    【算法笔记】B1004 成绩排名
    【算法笔记】B1003 我要通过!
    【算法笔记】B1002 写出这个数
    【算法笔记】B1001 害死人不偿命的(3n+1)猜想
    JZOJ 3233. 照片
    JZOJ 1243. TreeCount
    JZOJ 1241. Number
  • 原文地址:https://www.cnblogs.com/Tuesdayzz/p/5758837.html
Copyright © 2020-2023  润新知