枚举子集用lowbit WA on 4 求解释
查看原帖
枚举子集用lowbit WA on 4 求解释
754639
I_Was_Spasmodic楼主2024/10/28 17:37

rt

#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=16;
const int inf=1<<30;
int lowbit(int x){return x&(-x);}
int W,n;
int dpt[1<<N],dpw[1<<N];
signed main()
{
	cin>>W>>n;
	for(int i=0;i<n;i++)cin>>dpt[1<<i]>>dpw[1<<i];
	for(int i=1;i<(1<<n);i++)
	{
		int pt=i-lowbit(i);
		dpt[i]=max(dpt[pt],dpt[lowbit(i)]);
		dpw[i]=dpw[pt]+dpw[lowbit(i)];
		if(dpw[i]>W)dpt[i]=inf;
	}
	for(int i=0;i<(1<<n);i++)
	{
		int x=i^((1<<n)-1);			// 枚举集合 i 的补集,向 i 中添加枚举的集合 x
		while(x)
		{
			dpt[i|x]=min(dpt[i|x],dpt[x]+dpt[i]); // 刷表,更新 i + x 集合
			x-=lowbit(x);			// 去掉一个元素,枚举下一个 x 的子集
		}
	}
	cout<<dpt[(1<<n)-1];
}

这个是另一种写法,我认为应该是等价的,但是这个就可以过

#include<bits/stdc++.h>
using namespace std;
const int N=16;
const int inf=1<<30;
int W,n;
int dpt[1<<N],dpw[1<<N];
int main()
{
	cin>>W>>n;
	for(int i=0;i<n;i++)cin>>dpt[1<<i]>>dpw[1<<i];
	for(int i=1;i<(1<<n);i++)
	{
		int pt=i-lowbit(i);
		dpt[i]=max(dpt[pt],dpt[lowbit(i)]);
		dpw[i]=dpw[pt]+dpw[lowbit(i)];
		if(dpw[i]>W)dpt[i]=inf;
	}
	for(int i=0;i<(1<<n);i++)
	{
		int m=i^((1<<n)-1);
		int x=m;			// 枚举集合 i 的补集,向 i 中添加枚举的集合 x
		while(x)
		{
			dpt[i|x]=min(dpt[i|x],dpt[x]+dpt[i]); // 刷表,更新 i + x 集合
			x=(x-1)&m;			// 去掉一个元素,枚举下一个 x 的子集
		}
	}
	cout<<dpt[(1<<n)-1];
}
2024/10/28 17:37
加载中...