完全背包问题
有N件物品和一个最多能背重量为W的背包。第i件物品的重量是weight[i],得到的价值是value[i] 。每件物品都有无限个(也就是可以放入背包多次),求解将哪些物品装入背包里物品价值总和最大。
完全背包和01背包问题唯一不同的地方就是,每种物品有无限件。
实例1:
背包最大重量为4
物品为:
|
重量 |
价值 |
物品0 |
1 |
15 |
物品1 |
3 |
20 |
物品2 |
4 |
30 |
解题思路
动态规划
参照01背包问题的核心代码
1 2 3 4 5 6
| for(int i = 0 ; i < item_num; i++){ for(int j = bagweight; j>=weight[i]; j--) { dp[j] = Math.max(dp[j], dp[j - weight[i]] + value[i]); } }
|
01背包问题遍历背包容量时从大到小遍历的可以保证每个物品仅被添加了一次
而完全背包问题物品可以添加多次,背包容量需要从小到大遍历
1 2 3 4 5 6
| for(int i = 0 ; i < item_num; i++){ for(int j = weight[i]; j<=bagweight; j++) { dp[j] = Math.max(dp[j], dp[j - weight[i]] + value[i]); } }
|
dp数组的状态如图

代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| public static void main(String[] args){ int[] weight = {1,3,4}; int[] value = {15,20,30}; int bagweight = 4; completeBagProblem(weight, value, bagweight);
} public static void completeBagProblem(int[] weight, int[] value, int bagweight){ int item_num = weight.length; int[] dp = new int[bagweight+1]; for(int i = 0 ; i < item_num; i++){ for(int j = weight[i]; j<=bagweight; j++) { dp[j] = Math.max(dp[j], dp[j - weight[i]] + value[i]); } }
System.out.println("完全背包问题的答案为:" + dp[bagweight]); }
|
- 时间复杂度:$O(m × n)$ , m背包容量,n为物品的数量
- 空间复杂度:$O(m)$