洛谷P1433吃奶酪

洛谷P1433吃奶酪

Title

思路

先预处理dis
设f[i][j]为i点状态j的距离
f[i][2i-1]=dis[0][i]
f[j][i]=min(f[j][i],f[k][i-2j-1]+dis[k][j])
1<=j,k<=n
ans=min(f[i][2n-1])

代码

#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
using namespace std;
double x[20],y[20],dis[20][20],f[20][32769];
int main()
{
    
    
	ios::sync_with_stdio(false);
	int n,i,j,k;
	double ans;
	memset(f,0x7f7f7f7f,sizeof(f));
	for(cin>>n,x[0]=y[0]=0,dis[0][0]=0,i=1; i<=n; i++)
		for(cin>>x[i]>>y[i],j=0; j<i; j++)
			dis[i][j]=dis[j][i]=sqrt((x[i]-x[j])*(x[i]-x[j])+(y[i]-y[j])*(y[i]-y[j]));
	for(i=1; i<=n; i++)f[i][1<<(i-1)]=dis[0][i];
	for(i=1; i<(1<<n); i++)
		for(j=1; j<=n; j++)
			if(i&(1<<(j-1)))
				for(k=1; k<=n; k++)
					if(i&(1<<(k-1))&&j!=k)
						f[j][i]=min(f[j][i],f[k][i-(1<<(j-1))]+dis[k][j]);
	for(ans=0x7f7f7f7f,i=1; i<=n; i++)ans=min(ans,f[i][(1<<n)-1]);
	printf("%.2lf",ans);
	return 0;
}

猜你喜欢

转载自blog.csdn.net/weixin_46975572/article/details/116395806