uva 116 - Unidirectional TSP(精心设计的测试数据)
2012-10-21 16:20
507 查看
题目
题目大意是说,一个数字矩阵,从第1列到最后一列,一步可以往右走、右上走、右下走。路权为这条路径上的数字之和。输出最小路权及字典序最小的路径。
这题的一大亮点是,如果采用遍历每条路径从而获得字典序最小的路径的话,必然会超时;或者要加上剪枝才能通过检测,但是我没有找到强有力的剪枝。求神牛指点。
正确的做法是从后往前转移状态,假如当前往右、右上、右下都一样最优,则选择右上,每一步都这样做,必定是字典序最小的路径。记录在当前位置做出的选择。
AC:
题目大意是说,一个数字矩阵,从第1列到最后一列,一步可以往右走、右上走、右下走。路权为这条路径上的数字之和。输出最小路权及字典序最小的路径。
这题的一大亮点是,如果采用遍历每条路径从而获得字典序最小的路径的话,必然会超时;或者要加上剪枝才能通过检测,但是我没有找到强有力的剪枝。求神牛指点。
正确的做法是从后往前转移状态,假如当前往右、右上、右下都一样最优,则选择右上,每一步都这样做,必定是字典序最小的路径。记录在当前位置做出的选择。
AC:
#include<cstdio> #include<cstring> #include<math.h> #include<stdlib.h> #include<algorithm> #include<ctime> #include<iostream> #define INF 1<<30 using namespace std; const int maxm=10+10; const int maxn=100+10; typedef int G[maxm][maxn]; G a,way,f; int main() { #ifndef ONLINE_JUDGE freopen("in1.txt","r",stdin); #endif int i,j; int m,n; while(scanf("%d%d",&m,&n)==2) { for(i=1;i<=m;i++) for(j=1;j<=n;j++) scanf("%d",&a[i][j]);//mistook:a[m] for(i=1;i<=m;i++) f[i] =a[i] ; for(j=n-1;j>=1;j--) for(i=1;i<=m;i++) { int &ans=f[i][j]; ans=INF; for(int k=-1;k<=1;k++) { int p=(i+k-1+m)%m+1; if(f[p][j+1]<ans) { ans=f[p][j+1]; way[i][j]=p; }else if(f[p][j+1]==ans && p<way[i][j]) { way[i][j]=p; } } ans+=a[i][j]; } int mm,ans=INF; for(i=1;i<=m;i++) if(f[i][1]<ans) { ans=f[i][1]; mm=i; } printf("%d",mm); int x=mm,y=1; while(y<n) { x=way[x][y]; printf(" %d",x); y++; } printf("\n%d\n",ans); } //printf("%.2lf\n",(double)clock()/CLOCKS_PER_SEC); return 0; } /* */非正确程序,卡时返回,不能通过,数据太强:
#include<cstdio> #include<cstring> #include<math.h> #include<stdlib.h> #include<algorithm> #include<ctime> #include<iostream> #define INF 1<<30 using namespace std; const int maxn=100+10; const int maxm=10+10; const int maxTimes=10000; bool vis[maxm][maxn]; int f[maxm][maxn]; int a[maxm][maxn]; int m,n; int dp(int i,int j) { int &ans=f[i][j]; if(vis[i][j]) return ans; vis[i][j]=true; if(j==1) return ans=a[i][j]; ans=INF; for(int k=-1;k<=1;k++) ans=min(ans,dp((i+k-1+m)%m+1,j-1)); ans+=a[i][j]; return ans; } int bestPath[maxn],path[maxn]; bool first; int times; bool findPath(int i,int j) { int k; if(j==0) { if(first) { memcpy(bestPath,path,sizeof(bestPath)); first=false; }else { for(k=1;k<=n;k++) if(path[k]!=bestPath[k]) break; if(path[k]<bestPath[k]) memcpy(bestPath,path,sizeof(bestPath)); } if(++times>maxTimes) return true; return false; } path[j]=i; for(k=-1;k<=1;k++) { int p=(i+k-1+m)%m+1; if(f[i][j]==f[p][j-1]+a[i][j]) { if(findPath(p,j-1)) return true; } } return false; } int main() { #ifndef ONLINE_JUDGE freopen("in.txt","r",stdin); #endif int i,j; while(scanf("%d%d",&m,&n)==2) { for(i=1;i<=m;i++) for(j=1;j<=n;j++) scanf("%d",&a[i][j]); memset(vis,0,sizeof(vis)); memset(f,0,sizeof(f)); for(i=1;i<=m;i++) dp(i,n); int A ,An; int ans=INF; for(i=1;i<=m;i++) if(f[i] <=ans) { if(f[i] <ans) { An=0; ans=f[i] ; } A[An++]=i; } first=true; for(i=0;i<An;i++) { times=0; findPath(A[i],n); } printf("%d",bestPath[1]); for(i=2;i<=n;i++) printf(" %d",bestPath[i]); printf("\n%d\n",ans); } //printf("%.2lf\n",(double)clock()/CLOCKS_PER_SEC); return 0; } /* */
相关文章推荐
- UVA 116 Unidirectional TSP 求最小路线 DP
- UVa 116 Unidirectional TSP(简单旅行商DP)
- UVA 116 Unidirectional TSP
- 例题9-4 UVa116 Unidirectional TSP(DP:多段图的最短路)
- Unidirectional TSP UVA - 116
- UVA 116 Unidirectional TSP(DP+记忆化搜索)
- uva 116 Unidirectional TSP【号码塔+打印路径】
- UVA 116 Unidirectional TSP
- Unidirectional TSP(UVA 116)
- UVA 116 Unidirectional TSP 经典dp题
- UVA - 116 Unidirectional TSP 多段图的最短路
- uva 116 Unidirectional TSP (DP)
- UVA 116 Unidirectional TSP——dp
- UVa 116 - Unidirectional TSP(dp)
- UVa:116 Unidirectional TSP
- UVa 116 Unidirectional TSP (DP)
- UVa 116 (多段图的最短路) Unidirectional TSP
- uva 116 - Unidirectional TSP
- UVa 116 Unidirectional TSP
- uva 116 Unidirectional TSP (DP)