混合背包问题

题目来源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
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
posted @ 2020-11-28 23:18  hnkjdx_react  阅读(79)  评论(0编辑  收藏  举报