• AcWing 5. 多重背包问题 II【二进制优化版本】


    题目传送门

    1、与朴素版本的区别

    区别在于数据范围变大了:现在是三个循环数据上限分别是(1000)(物品种数),(2000)(背包容积),第(i)种物品的体积、价值和数量的上限也是(2000),原来的每个数字上限都是(100)

    三重循环的话,计算次数就是 (1000 * 2000 * 2000=4000000000=4 * 1e9 =40)亿次

    (C++)一秒可以算(1e8)次,就是(1)亿次,(40)亿肯定会超时!

    2、二进制优化

    朴素多重背包做法的本质:将有数量限制的相同物品看成多个不同的(0-1)背包。

    优化的思路:比如我们从一个货车搬百事可乐的易拉罐(因为我爱喝不健康的快乐水~),如果存在(200)个易拉罐,小超市本次要的数量为一个小于(200)的数字(n),搬的策略是什么呢?

    A、一个一个搬,直到(n)为止。

    B、在出厂前打成(64)个一箱,(32)个一箱,(16)个一箱,(8)个一箱,(4)个一箱,(2)个一箱,(1)个一箱,最后剩下的打成(73)个一箱
    为什么要把剩下的(73)个打成一个包呢?不是再分解成(64),(32)这样的组合呢?这是因为我们其实本质是化解为(01)背包,一来这么分解速度最快,二来可以表示原来数量的任何子集,这样就(OK)了!

    3、C++ 代码

    #include <bits/stdc++.h>
    
    using namespace std;
    const int N = 12010, M = 2010;
    
    int n, m;
    int v[N], w[N];
    int f[M];
    
    //多重背包的二进制优化
    int main() {
        //优化输入
        ios::sync_with_stdio(false);
        cin >> n >> m;
    
        int cnt = 0;
        for (int i = 1; i <= n; i++) {
            //每行三个整数 a,b,s,用空格隔开,分别表示第 i 种物品的体积、价值和数量
            int a, b, s;
            cin >> a >> b >> s;
           
            //二进制优化,能打包则打包之,1,2,4,8,16,...
            int k = 1;
            while (k <= s) {
                cnt++;
                v[cnt] = a * k;
                w[cnt] = b * k;
                s -= k;
                k *= 2;
            }
            //剩下的
            if (s > 0) {
                cnt++;
                v[cnt] = a * s;
                w[cnt] = b * s;
            }
        }
        n = cnt;//数量减少啦
        //01背包
        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;
    }
    
  • 相关阅读:
    用python解析html--SGMLParser
    Python相对完美的URL拼接函数
    Java将视频转为缩略图--ffmpeg
    卡夫卡(kafka)
    Qt 学习之路 2
    QT的Paint 系统
    Qt的4个图像类QImage/QPixmap/QBitmap/QPicture 转
    QImage对一般图像的处理
    Hough变换-理解篇
    从零开始学习无人驾驶技术 --- 车道检测
  • 原文地址:https://www.cnblogs.com/littlehb/p/15370556.html
Copyright © 2020-2023  润新知