完全背包理论
正序遍历,先背包先物品都可以,
正序遍历的话,之前的物品价值还在,可以用上。
物品和背包都是有前面推出来,都可以。
但是其他的非纯理论的完全背包问题就要看场景,确定先背包还是先物品了
//先遍历物品,再遍历背包
private static void testCompletePack(){
int[] weight = {1, 3, 4};
int[] value = {15, 20, 30};
int bagWeight = 4;
int[] dp = new int[bagWeight + 1];
for (int i = 0; i < weight.length; i++){ // 遍历物品
for (int j = weight[i]; j <= bagWeight; j++){ // 遍历背包容量
dp[j] = Math.max(dp[j], dp[j - weight[i]] + value[i]);
}
}
for (int maxValue : dp){
System.out.println(maxValue + " ");
}
}
//先遍历背包,再遍历物品
private static void testCompletePackAnotherWay(){
int[] weight = {1, 3, 4};
int[] value = {15, 20, 30};
int bagWeight = 4;
int[] dp = new int[bagWeight + 1];
for (int i = 1; i <= bagWeight; i++){ // 遍历背包容量
for (int j = 0; j < weight.length; j++){ // 遍历物品
if (i - weight[j] >= 0){
dp[i] = Math.max(dp[i], dp[i - weight[j]] + value[j]);
}
}
}
for (int maxValue : dp){
System.out.println(maxValue + " ");
}
}
518. 零钱兑换 II
518. 零钱兑换 II - 力扣(LeetCode)
得到的是组合数
class Solution {
public int change(int amount, int[] coins) {
//dp数组,装满容量为j的背包,有dp[j] 种方法
int [] dp = new int[amount+1];
//初始化累加得到最终结果,且递推公式里没有+数组的字段,则初始为1
dp[0] = 1;
for(int i = 0;i<coins.length;i++){
for(int j = coins[i];j<=amount;j++){
//递推公式
dp[j]+=dp[j-coins[i]];
}
}
return dp[amount];
}
}
377. 组合总和 Ⅳ
377. 组合总和 Ⅳ - 力扣(LeetCode)
class Solution {
public int combinationSum4(int[] nums, int target) {
//dp数组,装满容量为j的背包,有dp[j] 种方法
int [] dp = new int[target+1];
dp[0] = 1;
for(int i = 0;i<=target;i++ ){//背包
for(int j = 0;j<nums.length;j++){
if (i >= nums[j]) {//要保证背包装的下物品
dp[i] += dp[i - nums[j]];
}
}
}
return dp[target];
}
}
总结
完全背包在处理多少种方法的时候,先物品再背包表示组合,先背包再物品表示排列
处理能不能装的下的时候,都可以。
拓展
爬楼梯一次可以不同的台阶的话,怎么搞
也是体现遍历顺序对背包问题的重要性,这里二刷的时候总结背包问题的时候好好整理一下,
今日任务完成。