双调旅行商问题


poj2677,

先对x排序,但这题已经排好序的了

dp[i][j]表示从点i开始往左直到最左边的点,然后再从左往右到j点且经过所有i左边的点所走的距离

#include <iostream>
#include <cmath>
#include <stdio.h>
#include <algorithm>
using namespace std;
#define LL long long
#define maxn 1111
#define mset(a) memset(a,0,sizeof a)
#define FR(a) freopen(a,"r",stdin);
#define FW(a) freopen(a,"w",stdout);
const int INF = (1<<29);
double dp[maxn][maxn];
int x[maxn],y[maxn],n;
double dis(int i,int j)
{
	return sqrt((x[i]-x[j])*(x[i]-x[j])+(y[i]-y[j])*(y[i]-y[j])+0.0);
}
void solve()
{
	for(int i=1;i<n;++i)
		for(int j=0;j<=i;++j)
		{
			dp[i][j]=INF;
			if(j<i-1)
				dp[i][j]=dp[i-1][j]+dis(i,i-1);
			else if(j==i-1)
				for(int k=0;k<=j;++k)
					dp[i][j]=min(dp[i][j],dp[k][j]+dis(k,i));
			else if(j==i)
				for(int k=0;k<i;++k)
					dp[i][j]=min(dp[i][j],dp[k][i]+dis(k,i));
			dp[j][i]=dp[i][j];
		}
}
int main()
{
	//FR("read.txt");
	while (~scanf("%d",&n))
	{
		mset(x);
		mset(y);
		mset(dp);
		for(int i=0;i<n;++i)
			scanf("%d%d",x+i,y+i);
		solve();
		printf("%.2lf\n",dp[n-1][n-1]);
	}
}

你可能感兴趣的:(双调旅行商问题)