代码随想录第44天| 518. 零钱兑换 II、377. 组合总和 Ⅳ

182 阅读1分钟

518. 零钱兑换 II

1. first idea

coins: face values every face value has infinite number. we need to use these money to fill the amount. The result is the number of combinations. This is definitely a complete packge question.

dp[j] means the number of combinations given the package with capacity of j.

If we can fill the package with the coins[i] exactly, the recursion:

dp[j]+=dp[jweight[i]]dp[j] += dp[j - weight[i]]

To initiate: dp[0]=1 because if the capability is 0, we need no coins, which is a combination.

class Solution:
    def change(self, amount: int, coins: List[int]) -> int:
        dp = [0] * (amount + 1)
        dp[0] = 1
        for idx in range(len(coins)):
            for cap in range(1, amount + 1):
                if cap >= coins[idx]:
                    dp[cap] += dp[cap - coins[idx]]
        return dp[-1]

377. 组合总和 Ⅳ

1. first idea

还是按照上一道题的解法,发现只有组合没有排列,怎样才能实现排列呢?

2. doc reading

顺序不同的序列被视作不同的组合。

如果求组合数就是外层for循环遍历物品,内层for遍历背包

如果求排列数就是外层for遍历背包,内层for循环遍历物品

如果把遍历nums(物品)放在外循环,遍历target的作为内循环的话,举一个例子:计算dp[4]的时候,结果集只有 {1,3} 这样的集合,不会有{3,1}这样的集合,因为nums遍历放在外层,3只能出现在1后面!

所以本题遍历顺序最终遍历顺序:target(背包)放在外循环,将nums(物品)放在内循环,内循环从前到后遍历

class Solution:
    def combinationSum4(self, nums: List[int], target: int) -> int:
        dp = [0] * (target + 1)
        dp[0] = 1
        for cap in range(1, target + 1):
            for idx in range(len(nums)):
                if cap >= nums[idx]:
                    dp[cap] += dp[cap - nums[idx]]
        return dp[-1]