LeetCode518, change exchange II (complete backpack problem)

Title description

https://leetcode-cn.com/problems/coin-change-2/
Insert picture description here

solution

Complete knapsack problem, frame:

  • Determining the state is what are the variables in the problem — 1. Different types of coins; 2. Total amount; 3. Number of coins used; Then according to the problem, we only need to use the first two quantities to describe the current problem , Indicating that the dp array is two-dimensional, and the two dimensions correspond to variables 1 and 2 respectively.
  • The definition of the dp array: dp[i][j] represents the number of ways that the first i coins can make up the amount of j. Strictly believe this definition
  • Determine the recurrence process: if the i-th coin can be loaded, I can choose not to install, then dp[i][j] = dp[i-1][j], choose to install, then p[i][j] = dp[i][j-coins[i-1]], so in this case dp[i][j] = dp[i-1][j]+dp[i][j-conis[i- 1]]; if it can’t fit, then dp[i][j] = d[i-1][j]
  • If the recursion cannot be successful, return to the second step, the definition of dp array is wrong, rethink the definition of dp array
  • Consider the boundary situation: dp[i][0] is the method for the amount to be 0. There is only one method, which is not to collect. The result of the question is 1, dp[0][j]=0, which means there is no gold coin to collect.

Finally we write the code:

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[coins.length+1][amount+1];//表示前i种硬币组合为j元的可能方法数
        //边界 dp[0][j]=0 dp[i][0]=1 
        for(int i=0;i<=coins.length;i++){
    
    
            dp[i][0] = 1;
        }
        //递推方程
        for(int i=1;i<=coins.length;i++){
    
    
            for(int j=1;j<=amount;j++){
    
    
                if(j-coins[i-1]>=0){
    
    //当前硬币装得下
                    dp[i][j] = dp[i-1][j] //不装
                                + dp[i][j-coins[i-1]];//装下该硬币,但是因为数量无限个,可以继续装
                }else//装不下
                    dp[i][j] = dp[i-1][j];
            }
        }
        return dp[coins.length][amount];


    }
}

Insert picture description here

Then we can see from the solution that dp[i][j] is related to the previous two states, and state compression can be used to reduce space complexity:

  • One-dimensional array dp[j]
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];//表示前i种硬币组合为j元的可能方法数
        //边界 dp[0][j]=0 dp[i][0]=1 
        dp[0] = 1;
        //递推方程
        for(int i=1;i<=coins.length;i++){
    
    
            for(int j=1;j<=amount;j++){
    
    
                if(j-coins[i-1]>=0){
    
    //当前硬币装得下
                    dp[j] = dp[j] //不装
                                + dp[j-coins[i-1]];//装下该硬币,但是因为数量无限个,可以继续装
                }
                // }else//装不下
                //     dp[j] = dp[j];
            }
        }
        return dp[amount];


    }
}

Insert picture description here

Guess you like

Origin blog.csdn.net/qq_44861675/article/details/114577408