您的位置:首页 > 其它

BZOJ 1190 梦幻岛宝珠

2017-03-15 15:42 447 查看
二进制分组背包。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int n,w;
long long f[45][1050],x,y;
int main()
{
while (scanf("%d%d",&n,&w)==2)
{
memset(f,0,sizeof(f));
if (n==-1 && w==-1) break;
for (int i=1;i<=n;i++)
{
scanf("%lld%lld",&x,&y);
int a,b=0;
while (!(x&1)) {x>>=1;b++;}
a=x;
for (int j=1000;j>=a;j--) f[b][j]=max(f[b][j],f[b][j-a]+y);
}
for (int i=0;i<=30;i++)
for (int j=1;j<=1000;j++)
f[i][j]=max(f[i][j],f[i][j-1]);
long long ans=0;
for (int i=1;i<=1000;i++) ans=max(ans,f[0][i]);
for (int i=1;i<=30 && (1<<i)<=w;i++)
for (int j=min(1000,w>>i);j>=0;j--)
for (int k=0;k<=j;k++)
{
f[i][j]=max(f[i][j],f[i][j-k]+f[i-1][min(2*k+(((w>>(i-1))&1)>0),1000)]);
ans=max(ans,f[i][j]);
}
printf("%lld\n",ans);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: