UVA1347(Tour)(DAG上的动态规划)
本题的难点主要在于状态的定义,即如何去表示节点的状态。
在紫书中,作者选择了dp(i,j)来表示第一个人走到了i点,第二个人走到了j点,且编号小于max(i,j)的节点都被走过。因为dp[i][j]和dp[j][i]是重复的,因此规定i>j。这样可以保证无后效性,因为小于max(i,j)的点都被选过了,接下来就是在大于max(i,j)里面选点,所以之后的状态不会影响到前面的状态。
接下来考虑状态如何转移,由于状态的定义,下一步只能向编号大于i的节点移动,那么可以是第一个人向前走一步,或者第二个人向前走一步。从而得到状态转移方程:
dp[i][j]=min(dp[i+1][j]+dist(i,i+1),dp[i+1][i]+dist(j,i+1)),其中dist表示两点间的欧几里得距离。
递归起点是dp[2][1]。递归边界时dp[n-1][j],因为此时只剩下最后一个点没有经过,且dp[n-1][j]=dist(n-1,n)+dist(j,n)。
自然,ans=dp[2][1]+dist(1,2)。时间复杂度O为(n2)
#include<bits/stdc++.h>
using namespace std;
const int INF=0x3f3f3f3f;
int n;
int x[1005];
int y[1005];
double dp[1005][1005];
double dist(int a,int b)