[背包DP] CODEVS 3269 混合背包

题目

CODEVS 3269

思路

参考背包九讲,抽象化以后的过程组合起来,简单+简单+简单 != 难。
这里写图片描述
这里写图片描述

代码

#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <algorithm>
#define _for(i,a,b) for(int i = (a); i<(b); i++)
#define _rep(i,a,b) for(int i = (a); i<=(b); i++)
using namespace std;

const int maxm = 200000 + 100;
int n, c, v, w, s, d[maxm];

int main() {
    scanf("%d%d", &n, &c);
    _for(i, 0, n) {
        scanf("%d%d%d", &v, &w, &s);
        if (s == 1) {  // 01背包
            for (int j = c; j >= v; j--)
                d[j] = max(d[j], d[j - v] + w);
        }
        else if (s == -1 || s*v >= c) {  // 完全背包
            _rep(j, v, c)
                d[j] = max(d[j], d[j - v] + w);
        }
        else {  // 多重背包
            int k = 1;
            while (k < s) {
                for (int j = c; j >= k*v; j--)
                    d[j] = max(d[j], d[j - k*v] + k*w);
                s -= k;
                k *= 2;
            }
            for (int j = c; j >= s * v; j--)
                d[j] = max(d[j], d[j - s * v] + s * w);
        }
    }

    int ans = 0;
    _rep(i, 0, c) ans = max(ans, d[i]);
    printf("%d\n", ans);

    return 0;
}

猜你喜欢

转载自blog.csdn.net/icecab/article/details/81122155