求调
  • 板块P1433 吃奶酪
  • 楼主xxnn
  • 当前回复0
  • 已保存回复0
  • 发布时间2024/9/23 23:08
  • 上次更新2024/9/24 14:56:21
查看原帖
求调
1098382
xxnn楼主2024/9/23 23:08
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<climits>
using namespace std;
const int N = 2e2 , M = (1<<15) + 10;
 double x[N],y[N];
int n;
bool vis[N];
double f[M][N];//第一维为状态压缩下二进制走过的点,第二维为当前的点 
double ans = INT_MAX;

double dis(int x1,int x2)
{
	sqrt(((x[x1]-x[x2]) * (x[x1]-x[x2])) + ((y[x1]-y[x2]) * (y[x1]-y[x2])));
}

void dfs(int k,int now,double s,int t_base)
{
	//if(s>ans) return ;
	if(k==n)
	{
		if(ans>s)
			ans = s;
		return;
	}
	
	for(int i=1;i<=n;i++)
	{
		if(vis[i]) continue;
		//状压存状态 
		int mark = t_base + (1<<(i-1));//记录当前走过的点
		//  10010 代表走过第2,5的点    t_base 可代表过去走过的第2的点
		//   	然后 在2^(i-1)上的位置(即第5的点) 记录状态
		//  (因为二进制第一位是从从右往前数第二个位置开始的,而记录点是第一位就开始算的,所以得>>(i-1)) 
		if(f[mark][i]!=0 && f[mark][i] <= s + dis(now,i)) continue;
		//如果已经搜索过这个点(即!=0) 并且当前的路径f[mark][i]是最min的 就continue 
		vis[i]=1; 
		f[mark][i] = s+dis(now,i);
		
		dfs(k+1,i,f[mark][i],mark);
		vis[i] = 0;//解除标记 
	}
	return ;
}
int main()
{	
	scanf("%d",&n);
	for(int i=1;i<=n;i++)

		scanf("%lf%lf",&x[i],&y[i]);

	//memset(f,127,sizeof(f));
	//memset(vis,0,sizeof(vis));
	dfs(0,1,1,0);
	printf("%.2lf",ans);	
	return 0;
}
2024/9/23 23:08
加载中...