引言
完全背包隶属于动态规划中的背包问题。01 背包是完全背包的基石,建议先了解 01 背包。
什么是完全背包?
**01 背包问题:**有一个背包承重为 V,有 N 个物品,每个物品的价值 (value) 为 v,重量为 (weight) 为 w,每个物品只能取 1 次,求问背包最多能装下多大价值的物品。
**完全背包问题:**有一个背包承重为 V,有 N 个物品,每个物品的价值 (value) 为 v,重量为 (weight) 为 w,每个物品无限次存取,求问背包最多能装下多大价值的物品。
区别在于物品是否可以无限次存取。
举例
如题:一个能称重为 4 的背包,共有 3 件可装物品。对应价值与重量如下图所示,求最多能装下多大价值的物品。
1. 状态定义
dp[i][j] 表示,物品 [0~i] 每个物品,每个物品能取无数次,放入到容量为 j 的背包内,价值总和最大为多少。
2. 递推公式
拿 dp[1][4] 举例,物品 1,价值 value(20),重量 weight(3)。 有两种情况:
- 不选择物品本身:直接继承物品 0,即 dp[0][4] = 60;
- 选择该物品:dp[1][4-weight] + value = dp[1][1] + 20 也就是 35;
从两种选择中选取最大值。
递推公式:dp[i][j] = max(dp[i-1][j], dp[i][j-weight] + value);
3. 二维 DP 代码
#include <iostream>
#include <vector>
using namespace std;
int main(){
int bagweight = 6;
vector<int> weight = {1, 3, 4, 5, 6};
vector<int> value = {1, 3, 4, 5, 6};
// dp[i][j] 表示前 i 个物品放入容量为 j 的背包中所能获得的最大价值
vector<vector<int>> dp(weight.size(), vector<int>(bagweight + 1, 0));
( i = ; i <= bagweight; ++i){
(i < weight[]) {
dp[][i] = ;
} {
dp[][i] = dp[][i - weight[]] + value[];
}
}
( i = ; i < weight.(); ++i){
( j = ; j <= bagweight; ++j){
(j < weight[i]) {
dp[i][j] = dp[i - ][j];
} {
dp[i][j] = (dp[i - ][j], dp[i][j - weight[i]] + value[i]);
}
}
}
;
}


