/*----UVa1347 ---首相两边方向走不方便,可以看做:两个人同时从最左边出发,沿着两条不同路径走到终点,除了起点和中点外 其他点恰好被走过一遍 ---用dp[i][j]表示1-max(i,j)全部走过,且两人当前位置为i和j,还需要走多少距离。考虑到d[i][j]==dp[j][i],以下规定 i>j,此时后状态dp[i][j]只可以转移到dp[i+1][j]和dp[i+1][i](本来是dp[i][i+1],但是规定了i>j),考虑到边界条件 dp[n-1][j]=dis[n-1][n]+dis[n][j].一开始第一个人必定走到第2个点,最后求dis[1][2]+dp[2][1]; */ #define _CRT_SECURE_NO_DEPRECATE #include<iostream> #include<vector> #include<string.h> #include<math.h> #include<algorithm> using namespace std; const int maxn = 100; double dp[maxn][maxn],dis[maxn][maxn]; double x[maxn], y[maxn]; int main(){ int i, j, n; while (~scanf("%d", &n)){ for (i = 1; i <= n; i++) scanf("%lf%lf", &x[i], &y[i]); for (i = 1; i <= n; i++){ for (j = i; j <= n; j++) dis[i][j] = dis[j][i] = sqrt((x[i] - x[j])*(x[i] - x[j]) + (y[i] - y[j])*(y[i] - y[j])); } for (i = n - 1; i > 1; i--){ for (j = 1; j < i;j++) if (i == n - 1) dp[n - 1][j] = dis[n - 1][n] + dis[n][j]; //边界条件 else dp[i][j] = min(dp[i + 1][i] + dis[i+1][j], dp[i + 1][j] + dis[i][i + 1]); } printf("%.2lf ", dp[2][1] + dis[1][2]); } return 0; }