• AcWing 7. 混合背包问题


    题目传送门

    • 完全背包
      不是真正意义的无数量上限,而是受限于整体的体积\(V\)与当前物品的体积\(v_i\)的商:\(S_i=V\%v_i\),这样的话,完全背包可以看成多重背包。

    • 多重背包
      多重背包通过二进制优化可以打包成多个中间包,视为\(01\)背包

    • 完全转化为多重->多重通过二进制转化为\(01\)->利用\(01\)模板解决问题

    #include <bits/stdc++.h>
    
    using namespace std;
    const int N = 1e5 + 10;
    int n;      //物品种类
    int m;      //背包容量
    int v[N];   //物品体积
    int w[N];   //物品价值
    int f[N];   //dp数组
    int idx;
    
    int main() {
        cin >> n >> m;
    
        //二进制打包
        for (int i = 1; i <= n; i++) {
            int vi, wi, si;
            //体积,价值,个数
            cin >> vi >> wi >> si;
            if (si == -1)si = 1;            //题目中s=-1表示只有1个
            else if (si == 0)si = m / vi;    //完全背包(其实本质上就是多重背包):最多总体积/该物品体积向下取整
            //如果是其它大于0的数字,那么是多重背包
    
            //将完全背包和多重背包利用二进制优化转化为01背包
            int k = 1;
            while (k <= si) {
                v[++idx] = vi * k;
                w[idx] = wi * k;
                si -= k;
                k *= 2;
                idx++;
            }
            //剩余部分独立成包
            if (si > 0) {
                v[idx] = si * vi;
                w[idx] = si * wi;
                idx++;
            }
        }
        //01背包
        for (int i = 1; i <= idx; i++)
            for (int j = m; j >= v[i]; j--)
                f[j] = max(f[j], f[j - v[i]] + w[i]);
        //输出
        printf("%d", f[m]);
        return 0;
    }
    
  • 相关阅读:
    Redis 数据结构之dict
    分布式一致性算法——paxos
    分布式事务、两阶段提交协议、三阶提交协议
    MySQL主从数据同步延时分析
    MySQL数据丢失情况分析
    INSERT ... ON DUPLICATE KEY UPDATE Syntax
    分布式系统的数据一致性
    分布式系统的BASE理论
    分布式系统的CAP理论
    性能指标体系构建
  • 原文地址:https://www.cnblogs.com/littlehb/p/15684873.html
Copyright © 2020-2023  润新知