代码随想录-2023/08/12

105 阅读1分钟

动态规划

518.零钱兑换II

完全背包问题: 每个硬币有无限个

  1. 外层遍历物品
  2. 内层遍历背包(升序遍历)
  3. 求不同方案的递推公式为: dp[j] = dp[j] + dp[j-coins[i]]

代码:

class Solution {
    // 典型的完全背包问题
    public int change(int amount, int[] coins) {
        int n = coins.length;
        int[] dp = new int[amount + 1];
        dp[0] = 1;
        // 先遍历物品
        for(int i=0; i < n; i++){
            // 再遍历背包 --- 背包正序遍历代表每个物品可以放入无限次
            for(int j=coins[i]; j <= amount; j++){
                dp[j] += dp[j-coins[i]];
            }
        }

        return dp[amount];
    }
}

377.组合总和IV

完全背包问题:

本题答案的元素顺序也算不同答案, 所以是求排列

  1. 外层遍历背包
  2. 内层遍历物品
  3. 求不同方案的状态转移方程: dp[j] = dp[j] + dp[j-coins[i]]

代码;

class Solution {
    public int combinationSum4(int[] nums, int target) {
        // 完全背包
        int[] dp = new int[target+1];
        dp[0] = 1;
        // 先遍历背包
        for(int j=0; j<target+1; j++){
            // 再遍历物品
            for(int i=0; i<nums.length; i++){
                if(j >= nums[i]){
                    dp[j] += dp[j-nums[i]];
                }
            }
        }
        return dp[target];
    }
}