zoukankan      html  css  js  c++  java
  • 单向TSP

    给出一个m行n列(m≤10,n≤100)的整数矩阵,从第一列任意一个位置出发,每次可以往右、右上或右下走一格,最终到达最后一列。

    要求经过整数之和最小。矩阵是环形的,即最后一行向下是第一行。输出路径上每列的行号。多解时,输出字典序最小的。

    下图是两个矩阵的最优路线

    Sample Input

    5 6

    3 4 1 2 8 6

    6 1 8 2 7 4

    5 9 3 9 9 5

    8 4 1 3 2 6

    3 7 2 8 6 4

    5 6

    3 4 1 2 8 6

    6 1 8 2 7 4

    5 9 3 9 9 5

    8 4 1 3 2 6

    3 7 2 1 2 3

    2 2

    9 10 9 10

    Sample Output

    1 2 3 4 4 5

    16

    1 2 1 5 4 5

    11

    1 1

    19

    转移方程很简单,设d(i,j)为从格子(i,j)出发到最后一列的最小开销。则:

                    d(i,j)=d(i,j)+min{d(i-1,j-1),d(i,j-1),d(i+1,j-1)}

    主要问题在于输出路径。这就需要在计算d(i,j)时记录 " 下一列的行号 " 的最小值。

    #include<cmath>
    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    using namespace std;
    #define ll long long
    
    const int maxx=10000;
    int G[maxx][maxx];
    int dp[maxx][maxx];
    int n,m,ar[3];
    
    int compare_min(int a,int b,int c){
        ar[0]=a,ar[1]=b,ar[2]=c;
        sort(ar,ar+3);
        return ar[0];
    }
    
    int main() {
        cin>>n>>m;
        for(int i=1;i<=n;i++)
            for(int j=1;j<=m;j++)
                cin>>G[i][j];
        for(int j=0,i=1;i<=n;i++)
            dp[i][j]=0;
        for(int j=1;j<=m;j++)
            for(int i=1; i<=n; i++) {
                if(i==1)
                    dp[i][j]=G[i][j]+compare_min(dp[n][j-1],dp[i][j-1],dp[i+1][j-1]);
                else if(i==n)
                    dp[i][j]=G[i][j]+compare_min(dp[i-1][j-1],dp[i][j-1],dp[1][j-1]);
                else
                    dp[i][j]=G[i][j]+compare_min(dp[i-1][j-1],dp[i][j-1],dp[i+1][j-1]);
            }
        int ans=(1<<30);
        for(int j=m,i=1;i<=n;i++)
            if(ans>dp[i][j])
                ans=dp[i][j];
        cout<<ans<<endl;
        int road[m],cns=0;
        for(int j=m;j>=1;j--) {
            for(int i=1;i<=n;i++) {
                if(dp[i][j]==ans) {
                    road[cns]=i;
                    break;
                }
            }
            ans=ans-G[road[cns]][j];
            cns++;
        }
        for(int i=m-1;i>=0;i--)
        cout<<road[i]<<" ";;
        cout<<endl;
        return 0;
    }
    View Code
  • 相关阅读:
    JSON
    Chromium 修改chrome.exe
    Chromium 修改任务管理器显示的Chromium
    winhttp get请求https
    string wstring 互转
    浏览器指纹在线监测获取网址
    咕了的构造题单总结
    Git 常用命令总结
    C# 网络地址是否有效
    IDEA如何从断点里获取对象所有数据
  • 原文地址:https://www.cnblogs.com/rlddd/p/9048564.html
Copyright © 2011-2022 走看看