代码随想录第四十四天
- Leetcode 518. 零钱兑换 II
- Leetcode 377. 组合总和 Ⅳ
Leetcode 518. 零钱兑换 II
题目链接: 零钱兑换 II
自己的思路:想不到,忘记这个递推公式了!!!而且初始化也要值得注意!
正确思路:由于这个题每个数可以取多次,那么说明这是一个完全背包问题,而且背包的容量就是amount,所以这个题就是在问有多少种组合可以把背包装满;直接动规五部曲:1、dp数组的含义:从题目的目的出发,这道题是求组合数,所以dp[j]就表示背包容量为j的时候的组合数;2、递推公式:这道题和前面零钱兑换的题一样,都是求组合数,可以直接使用前面的求组合数的递推公式,也就是dp[j]+=dp[j-coins[i]],因为当我们固定一个的数的时候,组合的情况是把其他数所有的情况加起来!3、dp数组的初始化:这道题要把dp[0]初始化为1,因为如果初始化为0的话,会一直加都是0,当然初始化为1也是比较有歧义的,没有什么具体物理意义;4、遍历顺序:这道题必须先遍历物品后遍历背包,因为求的是组合数,如果先遍历背包后遍历物品的话,那么每次初始化一个背包的容量,都是遍历一次之前已经遍历过的物品,会重复,比如会出现{1,2}和{2,1}两种情况,所以我们要先遍历物品后遍历背包才可以!!!5、打印dp数组:主要用于debug和对一些情况不了解的时候!!!
代码:
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++){ //背包dp[j]+= dp[j-coins[i]]; //递推公式}}return dp[amount];}
}
Leetcode 377. 组合总和 Ⅳ
题目链接: 组合总和 Ⅳ
自己的思路:基本和上一道题一样!!!!只不过这道题要求的时候排列数,因为顺序不同的话也是可以算做一种情况,所以我们要先遍历背包,后遍历物品!!!!
正确思路:
代码:
class Solution {public int combinationSum4(int[] nums, int target) {int[] dp = new int[target+1];dp[0]=1;for (int j=0;j<=target;j++){ //先遍历背包for (int i =0;i<nums.length;i++){ //后遍历物品if (j>=nums[i]) dp[j] += dp[j-nums[i]];}}return dp[target];}
}