您的位置:首页 > 其它

UVA 1347 Tour - 简单dp

2016-03-26 15:35 381 查看
题目描述

分析:

从左边走到右边,再从右边走到左边,不重复经过点,求最短路。

<=>从左边有两个人一起向右边走,不重复经过点,求最短路。

dp[x][y] : 第一个人在x,第二个人在y点,[1,max(x,y)]的点一定已经走过的最短路。

由于dp[x][y]=d[y][x],规定x>=y

dp[x][y]=min(dp[x][y],dp[x-1][y]+dist[x-1][x])

dp[x][x-1]=min(dp[x][x-1],dp[x-1][k]+dist[k][x]) 1<=k<=i-1

#include<cstdio>
#include<algorithm>
#include<cmath>
using namespace std;
#define MAXN 1000
int n,a[MAXN+10][2];
double dist[MAXN+10][MAXN+10],dp[MAXN+10][MAXN+10];

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