AcWing 5. 多重背包问题 II 用二进制变成背包问题

AcWing 5. 多重背包问题 II

在这里插入图片描述

y总的视频

最多能使用s次,我们就求出相应的二进制数
把他拆分二进制,然后可以用这些一堆2i(1-cnt)来组合成0-s的数,
在这里插入图片描述
如果不能形成想象的二进制数,那我们就把最后的没能形成的作为一部分算进去。然后变成一个背包问题。
可能到这一步你们还没有理解,比如说
7的二进制数是111
可以变成14+12+1*1
因为二进制最大是1,也就是只能用一次,背包问题同样也是,背包问题没搞明白的话,可以去看看以前的博文链接
所以代码就非常的简单了。
代码如下

#include<iostream>
#include<algorithm>

using namespace std;

const int N=25000,M=2010;

int cnt;
int vi[N],wi[N],f[M];

int n,m;

int main(void)
{
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++)
    {
        int v,w,s;
        scanf("%d%d%d",&v,&w,&s);
        int k=1;
        while(k<s)
        {
            cnt++;
            vi[cnt]=v*k;
            wi[cnt]=w*k;
            s-=k;
            k*=2;
        }
        if(s)
        {
            cnt++;
            vi[cnt]=v*s;
            wi[cnt]=w*s;
        }
    }
    for(int i=1;i<=cnt;i++)
    for(int j=m;j>=vi[i];j--)
    f[j]=max(f[j],f[j-vi[i]]+wi[i]);
    cout<<f[m];
}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值