20230726

发布时间 2023-07-26 16:45:08作者: Eutopiax7

复赛

完全背包

定义
有 n 种物品和一个容量为 v 的背包,第 i 种物品体积为 c[i],价值为 w[i],每种物品有无穷件,问如何选取物品放入背包,可使价值总和最大。

与01背包的区别
01背包一个物品只能选一件,而完全背包一个物品可以选多件

例题

时间:1s 空间:128M
题目描述:
一个旅行者有一个最多能用V公斤的背包,现在有n件物品,它们的重量分别是W1,W2,...,Wn,它们的价值分别为C1,C2,...,Cn。有的物品只可以取一次(01背包),有的物品可以取无限次(完全背包),有的物品可以取的次数有一个上限(多重背包)。求解将哪些物品装入背包可使这些物品的费用总和不超过背包容量,且价值总和最大。
输入格式:
第一行:二个整数,V(背包容量,V<=200),N(物品数量,N<=30);
第2..N+1行:每行三个整数Wi,Ci,Pi,前两个整数分别表示每个物品的重量,价值,第三个整数若为0,则说明此物品可以购买无数件,若为其他数字,则为此物品可购买的最多件数 (0≤Pi≤20) 。
输出格式:
仅一行,一个数,表示最大总价值。
样例输入:

10 3
2  1  0
3  3  1
4  5  4

样例输出:

11

提示:
选第一件物品1件和第三件物品2件。

代码

#include <bits/stdc++.h>
using namespace std;
int v, n;
int f[205] = {0};
int main() {
    cin >> v >> n;
    for (int i = 1; i <= n; i++) {
        int w;
        int c;
        int p;
        cin >> w >> c >> p;
        switch (p) {
            case 0://完全背包
                for (int j = w; j <= v; j++) {
                    f[j] = max(f[j - w] + c, f[j]);
                }
                break;
            case 1://01背包
                for (int j = v; j >= w; j--) {
                    f[j] = max(f[j - w] + c, f[j]);
                }
                break;
            default://多重背包
                for (int j = v; j >= w; j--) {
                    for (int k = 0; k <= p; k++) {
                        if (j - k * w < 0) {
                            break;
                        }
                        f[j] = max(f[j - k * w] + k * c, f[j]);
                    }
                }
                break;
        }
    }
    cout << f[v];
    return 0;
}