专栏文章

p1433

个人记录参与者 1已保存评论 0

文章操作

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

当前评论
0 条
当前快照
1 份
快照标识符
@miq442gc
此快照首次捕获于
2025/12/03 22:38
3 个月前
此快照最后确认于
2025/12/03 22:38
3 个月前
查看原文
状压大炮。
一眼大炮。“状压”型号的大炮的制动方式很复杂,主要是根据二进制这一位上面是 0011 来决定发射炮弹的型号。顾名思义,炮弹型号 fi,kf_{i,k} 就代表二进制为 kk 时走到点 ii 的炮弹。所以有 fi,k=min(fi,k,fj,k2i1+ai,j)f_{i,k} =\min (f_{i,k},f_{j,k-2^{i-1}}+a_{i,j})。(aa 数组表示两点间的距离)最后找出 max(fi,2n1)\max(f_{i,2^n-1}) 中间的最大值就行。
代码也是很简单……个蛋!
CPP
#include <bits/stdc++.h>
double dis[20][20];
double x[20], y[20];
double f[20][100010];
int n;
double diss(int v, int w)
{
	return sqrt((x[v] - x[w]) * (x[v] - x[w]) + (y[v] - y[w]) * (y[v] - y[w]));//算距离
}
int main()
{
	double ans;
	for (int i = 0; i < 20; i ++) for (int j = 0; j < 100010; j ++) f[i][j] = 1e9;
	ans = f[0][0];
	cin >> n
	for(int i = 1; i <= n; i ++)
	{
		cin >> x[i] >> y[i];
	}
	x[0] = 0; y[0] = 0;
	for(int i = 0; i <= n; i ++)
	{
		for(j = i + 1; j <= n; j ++)
		{
			a[i][j] = diss(i, j);
			a[j][i] = a[i][j];
		}
	}
	for(int i = 1; i <= n; i ++)
	{
		f[i][(1 << (i - 1))] = a[0][i];
	}
	for(int k=1; k < (1 << N); k ++)
	{
		for(int i = 1; i <= n; i ++)
		{
			if((k & (1 << (i - 1))) == 0)//i压根没走过不可能成为当前走到的点
				continue;
			for(int j = 1; j <= n; j ++)
			{
				if(i == j)//一样的话等于自己走到自己,wyy
					continue;
				if((k & (1 << (j - 1))) == 0)//j 没走自然不可能走到 i
					continue;
				f[i][k] = min(f[i][k], f[j][k - (1 << (i - 1))] + a[i][j]);
			}
		}
	}
	for(int i = 1; i <= n; i ++)
	{
		ans = min(ans, f[i][(1 << N) - 1]);
	}
	printf("%.2f\n", ans);
}

评论

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

正在加载评论...