Unidirectional TSP UVA - 116

题解:dp[ i ][ j ]表示从格子(i,j)出发到最后一列的最小开销。

以前看这道题,感觉不太好写。其思路有点像数字三角行,从后往前推,不过这道题还要处理很多细节,一是初始化,二是方向的问题 ,因为图是环形的,

三是记录路径(长知识了)。

代码摘自紫书

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<iostream>
 4 #include<algorithm>
 5 #define INF 1e8
 6 using namespace std;
 7 typedef long long ll;
 8 
 9 int m,n;
10 int map[200][200],dp[200][200];
11 
12 void solve()
13 {   int ans=INF,first=0,next[200][200];
14     
15     for(int j=n-1;j>=0;j--){
16         for(int i=0;i<m;i++){
17             if(j==n-1) dp[i][j]=map[i][j];
18             else{
19                 int d[3]={i,i-1,i+1};
20                 if(i==0) d[1]=m-1;
21                 if(i==m-1) d[2]=0;
22                 sort(d,d+3);      //重新排序,以便找到最小的字典序。
23                 
24                 dp[i][j]=INF;
25                 for(int k=0;k<3;k++){
26                     int v=dp[d[k]][j+1]+map[i][j];
27                     if(v<dp[i][j]) { dp[i][j]=v; next[i][j]=d[k]; } 
28                 }
29             }
30             if(j==0&&dp[i][j]<ans) { ans=dp[i][j]; first=i; } 
31         }
32     }
33     
34     printf("%d",first+1);
35     for(int i=next[first][0],j=1;j<n;i=next[i][j],j++) printf(" %d",i+1);
36     printf("\n%d\n",ans);
37 }
38 
39 int main()
40 {    while(cin>>m>>n){
41         for(int i=0;i<m;i++)
42             for(int j=0;j<n;j++)
43                 cin>>map[i][j];
44         solve();
45     }
46     return 0;
47 }

 

posted @ 2017-08-07 15:37  天之道,利而不害  阅读(205)  评论(0编辑  收藏  举报