第九章例题 C - Tour

/*SE:wn------王宁*/

#include<bits/stdc++.h>
using namespace std;
const int maxn=55;
double x[maxn],y[maxn],dp[maxn][maxn],dist[maxn][maxn];
/*第一部分是求线段长度,no need for explanation
  关键是第二部分
  我之前只有一个地方想不明白——参考紫书上面的解释
  为什么说 “如果一个人走到了i+2,他就不可能再走到i+1了”?
  lz绕回去不行吗?和几何有关吗?要 不能交叉而形成一个环吗? 
  In fact,原因在于题目说的go directly :
  goes strictly right back to the starting point and goes strictly left to right to the rightmost point
  所以当我们按照两个人从左往右走的思路,两个人的路经过的点也应该是升序的
  由此可见,不用 不能交叉 或者运用高深(我还不会)的几何知识来求解*/
int main()
{
	int n,i,j;
	while(~scanf("%d",&n))
	{
		for(i=1;i<=n;i++) scanf("%lf%lf",&x[i],&y[i]);
		for(i=1;i<=n;i++)
			for(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(i=n-1;i>=2;i--)
			for(j=1;j<i;j++)
			{
				
				if(i==n-1)
					dp[i][j]=dist[i][n]+dist[j][n];
				else
				//都是在条件转移的地方出错,都把一个中括号里面的东西写成另外一个 ,脑子清醒点
				//上次是dp[i][j]=min(dp[i][j],dp[i+t[j-1]][j-1]); 里的 i+t[j-1]写成i+t[j] 
				//这次是 dist[i][i+1]+dp[i+1][j],应该是i转移而j不动,却写成了 dist[i][i+1]+dp[i+1][i]
					dp[i][j]=min(dist[i][i+1]+dp[i+1][j],dist[j][i+1]+dp[i+1][i]);
			}
		printf("%.2lf\n",dist[1][2]+dp[2][1]);

	}
	return 0;
}

猜你喜欢

转载自blog.csdn.net/JXUFE_ACMer/article/details/81476828