题目大意:给你10^5个物品,有重量和价值, 求重量按位或不超过k的物品的最大价值
首先它是不可以dp的,因为与运算对于背包不能离散,所以考虑模拟入手
从最高位往下找,来保证小于k
若这一位是1,则这一位是0的一定可以成为答案,统计一次贡献,这一位是0、1的待定
若这一位是0,则这一位是1的一定不可以成为答案,减掉,这一位是0的待定
这样从最高位一直做到最后一位就可以了
注:
1、不要循环变量名
2、最后一位特判
码:
#include<iostream>
#include<cstdio>
using namespace std;
long long n,i,er[40],tot[40],tot2,j,k,ans,K;
bool shan[100005];
struct la
{
long long w,v;
}wp[100005];
int main()
{
scanf("%lld",&n);scanf("%lld",&K);
er[0]=1;
for(i=1;i<=30;i++)
er[i]=er[i-1]*2;
for(i=1;i<=n;i++)
{
scanf("%lld%lld",&wp[i].w,&wp[i].v);
tot2+=wp[i].v;
for(j=0;j<=30;j++)
{
if((er[j]&wp[i].w)==0)
{
tot[j]+=wp[i].v;
}
}
}
for(i=30;i>=0;i--)
{
if((K&er[i])==0)
{
for(j=1;j<=n;j++)
{
if(wp[j].w&er[i])
{
if(shan[j]==0)
{
shan[j]=1;
for(k=0;k<=30;k++)
if((er[k]&wp[j].w)==0)
{tot[k]-=wp[j].v; }
tot2-=wp[j].v;
}
}
}
// ans=max(ans,tot[i]);
}else
{
ans=max(ans,tot[i]);
}
}
if((K&1)==1)ans=max(ans,tot2);
else ans=max(ans,tot[0]);
printf("%lld",ans);
}