算法修炼Day44|● 完全背包 ● 518. 零钱兑换 II ● 377. 组合总和 Ⅳ

59 阅读1分钟

完全背包:背包容量一定,每个物品数量不限,装满背包最多有多少种方法。

LeetCode:518. 零钱兑换 II - 力扣(LeetCode)

1.思路

物品数量不限,背包容量一定,装满背包的所有方法。

2.代码实现
class Solution {
    public int change(int amount, int[] coins) {
        int[][] dp = new int[coins.length][amount + 1];
        // 初始化:只有一种硬币的情况
        for (int i = 0; i <= amount; i += coins[0]) {
            dp[0][i] = 1;
        }
        for (int i = 1; i < coins.length; i++) { // 硬币种类
            for (int j = 0; j <= amount; j++) { // 背包容量控制?
                // 第 i 种硬币使用0 ~ k次,求和
                for (int k = 0; k * coins[i] <= j; k++) {
                    dp[i][j] += dp[i - 1][ j - k * coins[i]];
                }
            }
        }
        return dp[coins.length - 1][amount];
    }
}
3.复杂度分析:

时间复杂度:O(N * M).

空间复杂度:O(N).

LeetCode:377. 组合总和 Ⅳ - 力扣(LeetCode)

1.思路

当前状态是由前一状态推导出来的。

2.代码实现
class Solution {
    public int combinationSum4(int[] nums, int target) {
        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];
    }
}
3.复杂度分析:

时间复杂度:O(N * M).

空间复杂度:O(N).