UVA 1347 Tour - 简单dp

来源:互联网 发布:恋恋有词软件 编辑:程序博客网 时间:2024/05/20 06:56

题目描述

分析:

从左边走到右边,再从右边走到左边,不重复经过点,求最短路。
<=>从左边有两个人一起向右边走,不重复经过点,求最短路。
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 1000int 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][n-1]+dist[n-1][n]);}int main(){    while(scanf("%d",&n)==1){        read();        DP();    }}
0 0
原创粉丝点击