题意 http://www.cnblogs.com/kevinLee-xjtu/archive/2011/12/06/2299100.html
解法资料: http://www.cnblogs.com/kevinLee-xjtu/archive/2011/12/06/2299100.html
#include <iostream>
#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstring>
using namespace std;
const int M = 205;
const int inf = 9999999;
double dist[M][M];
double dp[M][M];
struct node {
double x, y;
}point[M];
double ans;
int n;
bool cmp(node p1, node p2){
if(p1.x != p2.x)
return p1.x < p2.x;
return p1.y < p2.y;
}
void init(){
ans = 0;
memset(dp, 0, sizeof(dp));
}
void input(){
for(int i = 1; i <= n; i++){
scanf("%lf%lf", &point[i].x, &point[i].y);
}
}
double getdis(int i, int j){
return sqrt((point[i].x - point[j].x)*(point[i].x - point[j].x) + (point[i].y - point[j].y)*(point[i].y - point[j].y));
}
void work(){
sort(point+1, point + n +1, cmp);
for(int i = 1; i <= n; i++){
for(int j = i+ 1; j <= n; j++){
dist[i][j] = dist[j][i] = getdis(i, j);
}
}
dp[1][2] = dp[2][1] = dist[1][2]; //注意 i = 1 j = 2 的情况。
for(int i = 1; i < n; i++){
for(int j = i + 1; j <= n; j++){
double minn = inf;
if(i + 1 == j){
for(int k = 1; k < j-1; k++){
minn = min(minn,dp[k][i] + dist[k][j]);
}
if(minn != inf)
dp[i][j] = minn;
}else if(j - i > 1){
dp[i][j] = dp[i][j-1] + dist[j-1][j];
}
}
}
dp[n][n] = dp[n-1][n] + dist[n-1][n];
printf("%.2f\n", dp[n][n]);
}
int main()
{
while(scanf("%d", &n) != EOF){
init();
input();
work();
}
return 0;
}