题目大意:一个从最左端走到最有右端,再走回最左端,走完所有的点,给出所有的点的左边,求最短的路径是多少。
输入格式
第一行一个整数n
接下来n行,每行两个整数x,y,表示某个点的坐标。
输入中保证没有重复的两点,
保证最西端和最东端都只有一个点。
7
0 6
1 0
2 3
5 4
6 1
7 5
8 2
0 6
1 0
2 3
5 4
6 1
7 5
8 2
输出格式
一行,即最短回路的长度,保留2位小数。
25.58
思路:一个人从最左到最右最后回到最左点 ,并形成一个环,其实可以看成两个人都从最左点出发,然后以不同的路径到达最右点。dp[i][j] 表示第一个人从起点到i点的距离 加上 第二个人到j点的距离之和, dp[n-1][n-1] 即为所求
# include <cstdio>
# include <algorithm>
# include <cmath>
using namespace std ;
struct node
{
int x ;
int y ;
}a[1010] ;
double dp[1010][1010] ;
bool cmp (const node &a ,const node &b)
{
return a.x < b.x;
}
double dist(node a , node b)
{
return double (sqrt(double((a.x - b.x)) * double((a.x - b.x)) + double((a.y - b.y)) * double((a.y - b.y)))) ;
}
int main ()
{
int n ;
while(scanf("%d" , &n) != EOF)
{
int i , j ;
for (i = 0 ; i < n ; i++)
for (j = 0 ; j < n ; j++)
dp[i][j] = 1e60;
dp[0][0] = 0 ;
for (i = 0 ; i < n ; i++)
scanf("%d %d" , &a[i].x , &a[i].y) ;
sort(a , a+n , cmp) ;
for (i = 0 ; i < n ; i++)
for (j = 0 ; j < n ; j++)
{
int t = min(n-1 , max(i , j) + 1) ;
dp[i][t] = min(dp[i][t] ,dp[i][j] +dist(a[j] , a[t])) ;
dp[t][j] = min(dp[t][j] ,dp[i][j] +dist(a[i] , a[t])) ;
}
printf("%.2lf\n" , dp[n-1][n-1]) ;
}
return 0 ;
}