zoukankan      html  css  js  c++  java
  • 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;
    }
    
  • 相关阅读:
    【整理】Linux 下 自己使用的 debug宏 printf
    STM32学习笔记:创建标准库工程模板
    【闲谈】第一份实习(下)
    Ceres-Solver库入门
    ceres-solver库使用示例
    ceres-solver库编译说明
    October 23, 2013
    Pollution over East China : Image of the Day
    谈谈PCI的GXL
    InfoQ访谈:Webkit和HTML5的现状和趋势
  • 原文地址:https://www.cnblogs.com/littlehb/p/15684873.html
Copyright © 2011-2022 走看看