UVa 1347
一个很巧妙的思路,强制定义状态dp(i, j), (i> j)仅可以为(1,i)范围内所有节点都已走过,并且此刻一条环路被拆分为上下两条DAG,同时,强制下一个点必须走过i+1,并验证这种情况不会丢失解。
DP的状态定义,还需要更多题来体会
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <queue>
#include <cmath>
#include <vector>
using namespace std;
const int maxn= 55;
double x[maxn], y[maxn];
double dist[maxn][maxn], dp[maxn][maxn];
int main()
{
int n;
while (1== scanf("%d", &n)){
for (int i= 1; i<= n; ++i){
scanf("%lf %lf", x+i, y+i);
}
for (int i= 1; i<= n; ++i){
for (int j= 1; j<= n; ++j){
dist[i][j]= sqrt((x[i]-x[j])*(x[i]-x[j])+(y[i]-y[j])*(y[i]-y[j]));
}
}
for (int i= 1; i< n-1; ++i){
dp[n-1][i]= dist[i][n]+dist[n-1][n];
}
for (int i= n-2; i> 1; --i){
for (int j= 1; j< i; ++j){
dp[i][j]= min(dp[i+1][j]+dist[i][i+1], dp[i+1][i]+dist[j][i+1]);
}
}
printf("%.2lf\n", dp[2][1]+dist[2][1]);
}
}