有 N 种物品和一个容量是 V 的背包。
物品一共有三类:
每种体积是 vi,价值是 wi。
求解将哪些物品装入背包,可使物品体积总和不超过背包容量,且价值总和最大。
输出最大价值。
第一行两个整数,N,V,用空格隔开,分别表示物品种数和背包容积。
接下来有 N 行,每行三个整数 vi,wi,si,用空格隔开,分别表示第 i 种物品的体积、价值和数量。
输出一个整数,表示最大价值。
0<N,V≤1000
0<vi,wi≤1000
−1≤si≤1000
4 5 1 2 -1 2 4 1 3 4 0 4 5 2
8
按照输入物品可以使用的次数,分类处理,可划分为01背包和完全背包两类进行处理
1 #include <iostream> 2 #include <algorithm> 3 #include <vector> 4 5 using namespace std; 6 7 constexpr int N = 1010; 8 typedef struct { 9 int type; // 物品处理的类型:-1(01背包问题), 0(完全背包问题) 10 int volume; // 物品的体积 11 int weight; // 物品的价值 12 } goods; 13 14 int main() { 15 int n = 0; // 物品个数 16 int v = 0; // 背包容量 17 std::cin >> n >> v; // 输入物品数量和背包容量 18 vector<goods> goodsList; 19 for (int i = 0; i < n; i++) { 20 int volume = 0; // 物品的体积 21 int weight = 0; // 物品的价值 22 int s = 0; // 某件物品可以用几次 23 std::cin >> volume >> weight >> s; // 输入物品的体积、价值和可以用的次数 24 // 根据某件物品可以用的次数,将物品分类处理: 25 // s < 0时按照01背包处理, s == 0时按照完全背包处理, 其它情况就是多重背包需转换为01背包处理 26 if (s < 0) { 27 goodsList.push_back({-1, volume, weight}); 28 } else if (s == 0) { 29 goodsList.push_back({0, volume, weight}); 30 } else { 31 for (int k = 1; k <= s; k *= 2) { 32 s -= k; 33 goodsList.push_back({-1, k * volume, k * weight}); 34 } 35 if (s > 0) { 36 goodsList.push_back({-1, s * volume, s * weight}); 37 } 38 } 39 } 40 vector<int> dp(N , 0); 41 for (auto goods : goodsList) { 42 // 按照01背包问题处理 43 if (goods.type < 0) { 44 for (int j = v; j >= goods.volume; j--) { 45 dp[j] = max(dp[j], dp[j - goods.volume] + goods.weight); 46 } 47 } else { // 按照完全背包处理 48 for (int j = goods.volume; j <= v; j++) { 49 dp[j] = max(dp[j], dp[j - goods.volume] + goods.weight); 50 } 51 } 52 } 53 std::cout << dp[v] << endl; 54 return 0; 55 }