uva116

Posted pandaking

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了uva116相关的知识,希望对你有一定的参考价值。

也是一道线性递推的dp,用刘汝佳的说法叫做多段图dag,

他的解释方法叫::::::::多段图是一种特殊的dag,其节点可以分成若干个阶段,每个阶段只由上一个阶段所决定,

UVa116 Unidirectional TSP

 

题意:给定一个n*m的矩阵,要求从第一列的任何一行出发,每次沿右或右下或右上到达后面一列,最后到第m列任何一行整个路程的最小值,并且要求是字典序最小的。

但是书上代码是逆推的,我是顺推了,我感觉是我那儿写丑了吧,我的代码wa到炸,但是现在没有心情调了,先放上错误代码吧

技术分享图片
 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<algorithm>
 5 using namespace std;
 6 int n,m,ans=1e9+7,tip;
 7 int num[30][110];
 8 int path[30][110];
 9 int dp[30][110];
10 
11 void dfs(int k,int times){
12     if(times==1) {printf("%d ",k);return;}
13     dfs(path[k][times],times-1);
14     if(times!=m) printf("%d ",k);
15     else printf("%d
",k);
16 }
17 
18 int main(){
19     while(scanf("%d%d",&n,&m)!=EOF){
20         for(int i=1;i<=n;i++)
21             for(int j=1;j<=m;j++)
22                 scanf("%d",&num[i][j]);
23         memset(dp,0,sizeof(dp)),ans=1e9+7;
24         if(n==1){
25             ans=0;for(int i=1;i<=m;i++) ans+=num[1][i];
26             for(int i=1;i<m;i++) printf("1 ");printf("1
"); 
27             cout<<ans<<endl;
28             continue;
29         }
30         if(m==1){
31             for(int i=1;i<=n;i++) if(ans>num[i][1]) ans=num[i][1],tip=i;
32             cout<<tip<<endl;
33             cout<<ans<<endl;
34             continue;
35         }
36         for(int i=1;i<=n;i++) dp[i][1]=num[i][1];
37         for(int i=2;i<=m;i++){
38             for(int j=1;j<=n;j++){
39                 if(j==1){
40                     dp[j][i]=dp[n][i-1]+num[j][i],path[j][i]=n;
41                     if(dp[j][i]>=dp[j+1][i-1]+num[j][i])  dp[j][i]=dp[j+1][i-1]+num[j][i],path[j][i]=j+1;
42                     if(dp[j][i]>=dp[j][i-1]+num[j][i])  dp[j][i]=dp[j][i-1]+num[j][i],path[j][i]=j;
43                 }else if(j==n){
44                     dp[j][i]=dp[n][i-1]+num[j][i],path[j][i]=n;
45                     if(dp[j][i]>=dp[j-1][i-1]+num[j][i]) dp[j][i]=dp[j-1][i-1]+num[j][i],path[j][i]=j-1;
46                     if(dp[j][i]>=dp[1][i-1]+num[j][i])  dp[j][i]=dp[1][i-1]+num[j][i],path[j][i]=1;
47                 }else{
48                     dp[j][i]=dp[j+1][i-1]+num[j][i],path[j][i]=j+1;
49                     if(dp[j][i]>=dp[j][i-1]+num[j][i]) dp[j][i]=dp[j][i-1]+num[j][i],path[j][i]=j;
50                     if(dp[j][i]>=dp[j-1][i-1]+num[j][i])  dp[j][i]=dp[j-1][i-1]+num[j][i],path[j][i]=j-1;
51                 }
52             }
53         }
54         for(int i=1;i<=n;i++) if(ans>dp[i][m]) ans=dp[i][m],tip=i;
55         dfs(tip,m);
56         cout<<ans<<endl; 
57     }
58     return 0;
59 }
View Code

 

以上是关于uva116的主要内容,如果未能解决你的问题,请参考以下文章

Unidirectional TSP UVA - 116 多段图的最短路

Uva116 Unidirectional TSP

UVA 116 Unidirectional TSP

UVA - 116 Unidirectional TSP

Uva 116,单向TSP

UVA 116 -- Unidirectional TSP(DP)