LeetCode337/518 Combination Sum 4/ Coin Change 2

Coin Change2:
use limit kind of coins and infinite number of coins to make a change.
this is a classic dp problem,
suppose the value of change we are gonna make is amount.
dp[i] means the number of ways to make a change for the value is i.

class Solution {
    public int change(int amount, int[] coins) {
        if(amount == 0) return 1;
        if(coins == null || coins.length == 0) return 0;
        
        int[] dp = new int[amount + 1];
        dp[0] = 1;
        
        for(int i = 0; i<coins.length; i++) {
            for (int j = 1; j<=amount; j++) { //
                if(j-coins[i] >= 0) {
                    dp[j] += dp[j - coins[i]]; 
                }
            }
        }
        return dp[amount];
    }
}

LC377 Combination Sum 4
Now, this problem is very much similar to pprevious problem, the only difference is, now we can only use each of the value once maximum. so now how many ways of combination so the sum of them is Target?

class Solution {
    public int combinationSum4(int[] nums, int target) {
        
        if(target == 0) return 1;
        if(nums == null || nums.length == 0) return 0;
        
        int[] dp = new int[target+1];
        for(int i = 1; i<=target; i++) {
            dp[i] = 0;
        }
        dp[0] = 1;
        
        //so the general idea of follow for loops, is: for each target, we will try all the coins, if we can use this coin, then fine. after we used this coin, nothing is change in nums[] becasue each one of them has unlimited number.
        for(int i = 1; i<=target; i++) {
            for(int j = 0; j<nums.length; j++) { //try every kind of coin
                if(i-nums[j] >= 0) { //if current coin value <= current target, means we can cover it. so now dp[i] is its origianl number of ways plus if we choose nums[j]
                    dp[i] += dp[i-nums[j]];
                }
            }
        }
        return dp[target];
    }
}

As you can see from those two problem, the coin change2 have:

        for(int i = 0; i<coins.length; i++) {
            for (int j = 1; j<=amount; j++) { //
                if(j-coins[i] >= 0) {
                    dp[j] += dp[j - coins[i]];  //pay attention to this atatement
                }
            }
        }
        return dp[amount];

and the combination sum 4 have:

        for(int i = 1; i<=target; i++) { 
            for(int j = 0; j<nums.length; j++) { //try every kind of coin
                if(i-nums[j] >= 0) { //if current coin value <= current target, means we can cover it. so now dp[i] is its origianl number of ways plus if we choose nums[j]
                    dp[i] += dp[i-nums[j]]; //pay attention to this statement
                }
            }
        }
        return dp[target];

so coin change2, for every kind of coins, we try dp[1] to dp[amount]
and combinatoin sum4, for every amount, which is dp[1] to dp[amount], we try every kind of coins, so that every kind of coin will be used once for a fixed amount.

posted @ 2020-06-08 01:01  EvanMeetTheWorld  阅读(26)  评论(0)    收藏  举报