多重背包Ⅱ

多重背包Ⅱ其实就是数据范围扩大了,不能写像昨天y总三层循环的那样了

然后然后然后新的做法似曾相识,嘿嘿嘿。这不就是我喜欢的简单粗暴的拆成01背包的那种做法吗

不过啦,数据范围是1000,那么简单粗暴行不通,必超时,所以在那个基础上进行二进制优化

哈哈哈,二进制优化真简单,一看就懂~(吹牛逼的)

反之

看了好几遍没看懂....

但是结合几个大佬的讲解,我有了自己的一种新的境界~~(仙气飘飘)

好了啊,废话不多说,直接上题

有 NN 种物品和一个容量是 VV 的背包。

第 ii 种物品最多有 sisi 件,每件体积是 vivi,价值是 wiwi。

求解将哪些物品装入背包,可使物品体积总和不超过背包容量,且价值总和最大。
输出最大价值。

输入格式

第一行两个整数,NVN,V,用空格隔开,分别表示物品种数和背包容积。

接下来有 NN 行,每行三个整数 vi,wi,sivi,wi,si,用空格隔开,分别表示第 ii 种物品的体积、价值和数量。

输出格式

输出一个整数,表示最大价值。

数据范围

0<N10000<N≤1000
0<V20000<V≤2000
0<vi,wi,si20000<vi,wi,si≤2000

提示:

本题考查多重背包的二进制优化方法。

输入样例

4 5
1 2 3
2 4 1
3 4 3
4 5 2

输出样例:

10
这个题思路啥的我都知道了,就是二进制开优化有点懵懵的,怎么说呢,举个例子吧
原来直接枚举的时候,比如有10个,可能选到第7个是最优解
然后后面三个枚举到的时候就是呈现不选的状态
用二进制优化的时候,2^0,2^1,2^2...把这些数字分堆,依然可以达到一一枚举的效果
比如107还是最优解
1 2 4 8
1+2+4==7
就是emm怎么说呢
后面的数字分为一堆,就不用一一枚举了,前面的数相加可以达到7的这个效果,,,这么说吗?
自己悟吧,哈哈...
复制代码
#include<iostream>
using namespace std;
const int N=1e5+10;
int f[N],v[N],w[N];
int main(){
    int n,m;
    cin>>n>>m;
    int t=0;
    for(int i=0;i<n;i++)
    {
        int a,b,c;
        cin>>a>>b>>c;
        int k=1;
        while(k<=c)
        {
            t++;
            v[t]=a*k;//t就是存数组的下标 
            w[t]=b*k;//k是二进制分堆 
            c-=k;//已经分出去的份数
            k*=2;//二进制优化,
        }
        if(c>0)
        {
            t++;
            v[t]=a*c;
            w[t]=b*c;
        }
    } 
    n=t;
    for(int i=1;i<=n;i++)
    {
        for(int j=m;j>=v[i];j--)
        {
            f[j]=max(f[j],f[j-v[i]]+w[i]);
        }
    }
    cout<<f[m]<<endl;
    return 0;
}
复制代码

看代码还是容易理解的,没啥好说的了,加油吧!!

 
posted @   小志61314  阅读(24)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具
点击右上角即可分享
微信分享提示