HDU 2224 The shortest path 双调旅行商问题
题目来源:HDU 2224 The shortest path
题意:求从1到n 然后在从n到1的最短路 去的时候经过的点的顺序必须从小到大 来的时候经过的点的顺序必须从大到小 并且每个点只能经过一次(1和n不算) 输出最短路的长度
思路:经典题 参考了大牛http://www.cppblog.com/doer-xee/archive/2009/11/30/102296.html
#include
#include
#include
using namespace std;
const int maxn = 210;
double dp[maxn][maxn];
double d[maxn][maxn];
struct point
{
double x, y;
}a[maxn];
double dis(int i, int j)
{
return sqrt((a[i].x-a[j].x)*(a[i].x-a[j].x)+(a[i].y-a[j].y)*(a[i].y-a[j].y));
}
int main()
{
int n;
while(scanf("%d", &n) != EOF)
{
for(int i = 1; i <= n; i++)
scanf("%lf %lf", &a[i].x, &a[i].y);
for(int i = 1; i <= n; i++)
{
for(int j = 1; j <= n; j++)
{
d[i][j] = dis(i, j);
}
}
dp[1][2] = d[1][2];
for(int i = 3; i <= n; i++)
{
for(int j = 1; j < i-1; j++)
dp[j][i] = dp[j][i-1] + d[i-1][i];
dp[i-1][i] = 999999999.0;
for(int j = 1; j < i-1; j++)
{
double sum = dp[j][i-1] + d[j][i];
if(dp[i-1][i] > sum)
dp[i-1][i] = sum;
}
}
dp[n][n] = dp[n-1][n] + d[n-1][n];
printf("%.2f\n", dp[n][n]);
}
return 0;
}