您的位置:首页 > 其它

Uva116 Unidirectional TSP

2017-07-28 20:57 357 查看
题目描述



这是一道简单的DP题,记录路径可以用一个p数组;

设f(i,j)为从格子i,j出发到最右端的最小数字和。

边界是f(n−1,j)=a(n−1,j)

我的程序n和m是反的,,,

#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<cstdlib>
#include<cmath>
using namespace std;
const int INF=2000000;
const int d[]={-1,0,1};
int f[200][200],a[200][200],p[200][200];
int n,m;
int main(){
while(cin>>n>>m&&n&&m){
for(int i=0;i<n;i++)
for(int j=0;j<m;j++)
scanf("%d",&a[j][i]);
for(int i=0;i<n;i++)
for(int j=0;j<m;j++)
f[j][i]=INF;
for(int i=0;i<n;i++){
f[m-1][i]=a[m-1][i];
p[m-1][i]=-1;
}
for(int i=m-2;i>=0;i--){
for(int j=0;j<n;j++){
for(int k=0;k<3;k++){
int jj=j+d[k];
if(jj<0) jj=n-1;
if(jj==n) jj=0;
if(f[i+1][jj]+a[i][j]<f[i][j]||(f[i+1][jj]+a[i][j]==f[i][j]&&jj<p[i][j])) //如果字典序更小也更新
f[i][j]=f[i+1][jj]+a[i][j],p[i][j]=jj;
}
}
}
int ans=INF,ansd;
for(int i=0;i<n;i++)
if(f[0][i]<ans) ans=f[0][i],ansd=i;
for(int i=ansd,j=0;i!=-1;i=p[j][i],j++) printf("%d%c",i+1,p[j][i]==-1?'\n':' ');
printf("%d\n",ans);
}
return 0;
}


时间复杂度O(n2)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: