UVA 116 Unidirectional TSP (DP)

4 篇文章 0 订阅

http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=52


题目大意:

矩阵上的数塔   要求求出一条路径  让路径上的和最小   只能走相邻的位置   题目中的图示就看懂了

要字典序最小  


思路:

 从右往左DP  

但是要注意当DP到第一行  最后一行的时候   优先判断哪一个的问题


 #include <cstdio>
 #include <algorithm>
 #include <cstring>
 #include <string>
 #define INF 0x3f3f3f3f
 using namespace std;

 int a[15][120];
 int st[15][120];


 int min(int x,int y)
 {
     return x>y?y:x;
 }

 int main()
 {
     int n,m;
     while(scanf("%d%d",&n,&m)!=EOF)
     {
         memset(a,0,sizeof(a));
         for(int i=0;i<n;i++)
         for(int j=0;j<m;j++)
         {
             scanf("%d",&a[i][j]);
         }
         for(int j=m-2;j>=0;j--)
         {
             for(int i=0;i<n;i++)
             {

                int tmp = min(a[i][j+1],min(a[((i-1)+n)%n][j+1],a[(i+1)%n][j+1]));
                a[i][j]+=tmp;

                if(i==n-1){
                    if(tmp==a[(i+1)%n][j+1])st[i][j]=(i+1)%n;
                    else if(tmp==a[(i-1+n)%n][j+1])st[i][j]=(i-1+n)%n;
                    else if(tmp==a[i][j+1])st[i][j]=i;
                }
                else if(i==0)
                {

                    if(tmp==a[i][j+1])st[i][j]=i;
                    else if(tmp==a[i+1][j+1])st[i][j]=(i+1)%n;
                    else if(tmp==a[(i-1+n)%n][j+1])st[i][j]=(i-1+n)%n;
                }
                else
                {
                    if(tmp==a[(i-1+n)%n][j+1])st[i][j]=(i-1+n)%n;
                    else if(tmp==a[i][j+1])st[i][j]=i;
                    else if(tmp==a[i+1][j+1])st[i][j]=(i+1)%n;
                }
             }
         }
      
        int ans=1<<30;
        //printf("%d \n",ans);
        int pos;
        for(int i=0;i<n;i++)
        {
           // ans=min(ans,a[i][0]);
            if(ans>a[i][0])
            {
                ans=a[i][0];
                pos=i;
            }
        }
        int cnt=0;
        bool first=true;
        while(cnt!=m)
        {
            if(first)printf("%d",pos+1),first=false;
            else printf(" %d",pos+1);

            pos=st[pos][cnt++];
        }
        puts("");
        printf("%d\n",ans);
     }
     return 0;
 }


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值