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]);
	}
}
posted @ 2020-09-30 15:25  IdiotNe  阅读(92)  评论(0编辑  收藏  举报