您的位置:首页 > 其它

UVA 1347 Tour

2014-07-30 09:49 375 查看
动态规划

题意可以理解为两个人同时从最左点出发,沿着两条不同的路径走到最右点(除了起点和终点每个点走且仅走一次)

状态 dp[i][j]指当前两人分别走到i,j点。且设i>j;

则有:dp[i+1][i]=min (dp[i+1][i],dp[i][j]+dist[i][i+1]);

   dp[i+1][j]=min (dp[i+1][j],dp[i][j]+dist[j][i+1]);

因为每个点都要走到,所以每次走到没走到的第一个点。

最终结果是 dp[n-1][i]+dist[i]
+dist[n-1]
;(0<i<n-1) 最终点要走两次。

#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>
#include <cmath>
using namespace std;

const double inf=99999999.0;
int n;
double a[1005][2];
double dist[1005][1005];
double dp[1005][1005];

double getdist (double x1,double y1,double x2,double y2){
double x,y;
x=fabs (x1-x2);
y=fabs (y1-y2);
return sqrt (x*x+y*y);
}

int main (){//cout<<inf<<endl;
while (~scanf ("%d",&n)){
for (int i=0;i<n;i++){
scanf ("%lf%lf",&a[i][0],&a[i][1]);
}
for (int i=0;i<n;i++)
for (int j=0;j<n;j++)
dist[i][j]=getdist (a[i][0],a[i][1],a[j][0],a[j][1]);//cout<<i<<" "<<j<<":"<<dist[i][j]<<"    ";
for (int i=0;i<=n;i++)
for (int j=0;j<=n;j++)
dp[i][j]=inf;
dp[0][0]=0;
for (int i=0;i<n-2;i++){
for (int j=0;(i==0&&j==0)||j<i;j++){
dp[i+1][j]=min (dp[i+1][j],dp[i][j]+dist[i][i+1]);
dp[i+1][i]=min (dp[i+1][i],dp[i][j]+dist[j][i+1]);//cout<<dp[i+1][j]<<" "<<dp[i+1][i]<<endl;
}
}//cout<<endl;
double ans=inf;
for (int i=0;i<n-2;i++)
ans=min (ans,dp[n-2][i]+dist[n-1][n-2]+dist[n-1][i]);//cout<<n-2<<" "<<i<<endl,cout<<dp[n-2][i]+dist[n-1][n-2]+dist[n-1][i]<<endl;
printf ("%.2f\n",ans);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: