Day37| 完全背包、518.零钱兑换II、377. 组合总和 Ⅳ、70. 爬楼梯 (进阶)
文章链接
完全背包
-
确定dp数组以及下标的含义 dp[i][j] 表示从下标为[0-i]的物品,每个物品可以取无限次,放进容量为j的背包,价值总和最大是多少。
-
确定递推公式
-
不放物品i:背包容量为j,里面不放物品i的最大价值是dp[i - 1][j]。
-
放物品i:背包空出物品i的容量后,背包容量为j - weight[i],dp[i][j - weight[i]] 为背包容量为j - weight[i]且不放物品i的最大价值,那么dp[i][j - weight[i]] + value[i] (物品i的价值),就是背包放物品i得到的最大价值 递推公式:
dp[i][j] = max(dp[i - 1][j], dp[i][j - weight[i]] + value[i]);
-
dp数组如何初始化
-
确定遍历顺序 既可以先遍历物品再遍历背包,也可以调换顺序
518.零钱兑换II
-
确定dp数组以及下标的含义 dp[i]装满背包容量j有dp[j]种方法
-
确定递推公式 dp[j]+=dp[j-coins[j]]
-
dp数组如何初始化 dp[0]=1,非0下标初始化为0
-
确定遍历顺序 先遍历物品再遍历背包是组合数 先遍历背包再遍历物品是排列数
public class Solution {public int Change(int amount, int[] coins) {int[] dp= new int[amount+1];dp[0]=1;for(int i=0;i<coins.Length;i++){for(int j=coins[i];j<=amount;j++){if(j>=coins[i]){dp[j] += dp[j - coins[i]];}}}return dp[amount];}
}
70. 爬楼梯 (进阶)
- 确定dp数组以及下标的含义
dp[i]:爬到有i个台阶的楼顶,有dp[i]种方法。
- 确定递推公式
在动态规划:494.目标和 (opens new window)、 动态规划:518.零钱兑换II (opens new window)、动态规划:377. 组合总和 Ⅳ (opens new window)中我们都讲过了,求装满背包有几种方法,递推公式一般都是dp[i] += dp[i - nums[j]];
本题呢,dp[i]有几种来源,dp[i - 1],dp[i - 2],dp[i - 3] 等等,即:dp[i - j]
那么递推公式为:dp[i] += dp[i - j]
- dp数组如何初始化
既然递归公式是 dp[i] += dp[i - j],那么dp[0] 一定为1,dp[0]是递归中一切数值的基础所在,如果dp[0]是0的话,其他数值都是0了。
下标非0的dp[i]初始化为0,因为dp[i]是靠dp[i-j]累计上来的,dp[i]本身为0这样才不会影响结果
- 确定遍历顺序
这是背包里求排列问题,即:1、2 步 和 2、1 步都是上三个台阶,但是这两种方法不一样!
所以需将target放在外循环,将nums放在内循环。
每一步可以走多次,这是完全背包,内循环需要从前向后遍历。