zoukankan      html  css  js  c++  java
  • 混合背包问题

    题目来源acwing7



    利用多重背包的二进制优化,可以将一种被扒皮分散为多个01背包,用三个a,b,c数组来记录转换之后的所有背包,c为bool型数组,如果为true,就是完全背包,false则为01背包,最后做一遍,以c的值分类。做完全背包和01背包

    #include <iostream>
    #include <cstdio>
    using namespace std;
    
    const int N = 1010, M = 10000;
    int f[N], g[N];
    int a[M], b[M];
    bool c[M]; // false: 完全背包, true: 01背包
    int n, m;
    
    int main()
    {
        cin >> n >> m;
        int inf = 0;
        for (int i = 0; i < n; i ++)
        {
            int v, w, s;
            scanf("%d%d%d", &v, &w, &s);
            if(!s){
                a[inf] = v;
                b[inf ++] = w;
                // c[inf ++] = s;
            }
            else
            {
                if(s == -1) s = 1;
                int k = 1;
                while(k <= s)
                {
                    a[inf] = k * v;
                    c[inf] = 1;
                    b[inf ++] = k * w;
                    s -= k;
                    k <<= 1;
                }
                if(s)
                {
                    a[inf] = s * v;
                    c[inf] = 1;
                    b[inf ++] = s * w;
                }
            }
        }
    
        for (int i = 0; i < inf; i ++)
        {
            if(c[i]){
                for (int j = m; j >= a[i]; j --)
                    f[j] = max(f[j], f[j - a[i]] + b[i]);
            }
            else{
                for (int j = a[i]; j <= m; j ++)
                    f[j] = max(f[j], f[j - a[i]] + b[i]);
            }
        }
    
        cout << f[m] << endl;
    
        return 0;
    }
    
    作者:Enchanted_77
    链接:https://www.acwing.com/solution/content/12711/
    来源:AcWing
    著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
    
  • 相关阅读:
    js 抓取距离的方法
    mysql 设置账户权限
    mysql 主从复制
    mysql 分区
    linux 安装samba
    linux 配置lamp
    linux 本地虚拟机配置
    linux 权限
    linux 磁盘分区
    mysql-进阶 if/while/case
  • 原文地址:https://www.cnblogs.com/hnkjdx-ssf/p/14054823.html
Copyright © 2011-2022 走看看