宝物筛选

多重背包问题

物品数目已知

可以枚举每个物品

当做01背包来做

不过会超时

此时需要二进制拆分来优化

分解成新的物品

再跑一遍01背包即可

//二进制拆分+01背包
//设f[j]表示前i件物品花费恰好为j的最大价值 
#include <cstdio>
#include <iostream>
using namespace std;
const int N = 1000000;
int n, m, f[N], v[N], w[N], cnt, a, b, c;
int read() {
    int s = 0, w = 1;
    char ch = getchar();
    while(!isdigit(ch)) {if(ch == '-') w = -1; ch = getchar();}
    while(isdigit(ch)) {s = s * 10 + ch - '0'; ch = getchar();}
    return s * w;
}
int main() {
    n = read(), m = read();
    for(int i = 1; i <= n; i++) {
        a = read(), b = read(), c = read();
        for(int j = 1; j <= c; j <<= 1) {
            v[++cnt] = a * j;
            w[cnt] = b * j;
            c -= j;
        }
        if(c) v[++cnt] = a * c, w[cnt] = b * c;
    }
    for(int i = 1; i <= cnt; i++)
        for(int j = m; j >= w[i]; j--)
            f[j] = max(f[j], f[j - w[i]] + v[i]);
    printf("%d\n", f[m]);
    return 0;
} 

谢谢收看, 祝身体健康!

01-21 21:00