[unknown OJ] 手套

博客围绕一个博弈问题展开,该问题中需确定 x 和 y,而选择结果由上帝决定。因 n 小,上帝有 2n 种组合拳。要抗住所有组合拳,y 需为 max(y0)。计算答案时,x 可不选完最少手套,y 多选 1 个可能撞色,同时要注意两个特判情况。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、题目

点此看题

二、解法

一开始的理解虽然无限接近正解却有失偏颇,还是用图灵蒋的方法写这篇博客吧。

首先一定要搞清楚这个问题其实是博弈,我们所做的只有确定 x x x y y y,而选出什么完全是上帝决定了。秉承这个思想,由于 n n n 很小,而上帝拥有 2 n 2^n 2n 种组合拳,也就是让你把一种手套全部选择左,一种手套全部选择右,这样的情况最坏,上帝会根据你选的 x , y x,y x,y 决定用哪种组合拳。

设每种组合拳所消耗的手套数分别是 x 0 x_0 x0 y 0 y_0 y0,那么对于我们选出的 x x x ,如果 x ≤ x 0 x\leq x_0 xx0,上帝就可能使用这种组合拳(因为这里的 x 0 x_0 x0 是最差的消耗呀),我们要能抗住上帝使用的所有组合拳,那么我们选择的 y y y 必须是 max ⁡ ( y 0 ) \max(y_0) max(y0)

计算答案的时候 x x x 可以不选完最少的那个手套(因为有这种手套就行,但上帝会给你最劣的选择), y y y 在多选 1 1 1 个手套就可以撞到和 x x x 相同颜色的手套(还有一种情况是 x x x 多选一个手套和 y y y 撞,仔细想想上面已经把他枚举了),注意的两点:特判 y y y 选满了不行,特判 x 0 x_0 x0 相等的时候要访问玩所有的 x 0 x_0 x0 才能取到 y y y 的最大值计算。

#include <cstdio>
#include <algorithm>
using namespace std;
const int M = 25;
const int inf = 2e9+7;
int read()
{
	int x=0,f=1;char c;
	while((c=getchar())<'0' || c>'9') {if(c=='-') f=-1;}
	while(c>='0' && c<='9') {x=(x<<3)+(x<<1)+(c^48);c=getchar();}
	return x*f;
}
int n,m,sumb,a[M],b[M],id[1<<20],sum[1<<20];
int lowbit(int x)
{
	return x&(-x);
}
bool cmp(int x,int y)
{
	return sum[x]<sum[y];
}
int main()
{
	freopen("gloves.in","r",stdin);
	freopen("gloves.out","w",stdout);
	n=read();m=1<<n;
	for(int i=1;i<=n;i++)
	{
		a[i]=read();
		sum[1<<i-1]=a[i];
	}
	for(int i=1;i<=n;i++)
	{
		b[i]=read();
		sumb+=b[i];
	}
	for(int i=1;i<m;i++)
	{
		int x=lowbit(i);id[i]=i;
		sum[i]=sum[i^x]+sum[x];
	}
	sort(id+1,id+m,cmp);
	int a1=inf,a2=0,mb=0;
	for(int i=m-1;i>=0;i--)
	{
		int sb=0,s=id[i];
		for(int j=1;j<=n;j++)
			if(!(s&(1<<j-1)))
				sb+=b[j];
		if(sumb==sb) break;//y不能选满 
		mb=max(mb,sb);
		if(sum[s]==sum[id[i-1]]) continue;//相同以后算
		//sum[id[i-1]]+1 即为最小的手套没有选满 
		if(sum[id[i-1]]+2ll+mb<=0ll+a1+a2)
		{
			a1=sum[id[i-1]]+1;
			a2=mb+1;
		}
	}
	printf("%d\n%d\n",a1,a2);
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值