专栏文章

UVA10911 Forming Quiz Teams 题解

UVA10911题解参与者 1已保存评论 0

文章操作

快速查看文章及其快照的属性,并进行相关操作。

当前评论
0 条
当前快照
1 份
快照标识符
@mioxra4h
此快照首次捕获于
2025/12/03 02:53
3 个月前
此快照最后确认于
2025/12/03 02:53
3 个月前
查看原文
注意到 n8n \le 8,这种范围并不需要状压 dp,普通的 dfs 也可以过。
11 号点开始枚举,如果一个点已经打了标记,说明这个点已经和其他点配对,直接枚举下一个点;否则再枚举一个点,并将枚举的两个点配对并打上标记。
注意需要回溯!!!
CPP
#include <iostream>
#include <cmath>
using namespace std;
int n,dis[20004],cnt;//dis是标记数组
double a[2005],b[2005];
string s;
double ans = 1e10;
double ju(int x,int y)//这是两点之间的距离公式
{
	return sqrt((a[x] - a[y]) * (a[x] - a[y]) + (b[x] - b[y]) * (b[x] - b[y]));
}
void dfs(int step,double sum)//step是枚举的点,sum是目前的距离总和
{
	if(sum > ans)return ;
	if(step > 2 * n)
	{
		ans = min(ans,sum);
		return ;
	}
	if(dis[step])dfs(step + 1,sum);
	else
	{
		for(int i = step + 1;i <= 2 * n;i ++)
		{
			if(dis[i])continue ;
			dis[step] = dis[i] = 1;//将这两个点分到一组
			dfs(step + 1,sum + ju(step,i));
			dis[step] = dis[i] = 0;
		}
	}
}
int main()
{
	while(cin >> n && n)
	{
		ans = 1e10;
		for(int i = 1;i <= 2 * n;i ++)cin >> s >> a[i] >> b[i];
		dfs(1,0);
		printf("Case %d: %.2lf\n",++cnt,ans);
	}
}

评论

0 条评论,欢迎与作者交流。

正在加载评论...