Address: https: //leetcode-cn.com/problems/coin-change/
Note two things:
1, dp
the upper limit value, since they are all integers, and therefore amount + 1
;
2, can be transferred from the place can be calculated starting;
3, and completely contact the knapsack problem is generated.
Method One: dynamic programming
The most basic use of "dynamic programming" ideas.
Step 1: Status Definitions
dp[i]
Make up represents the amount of i
the minimum number of coins.
Step 2: state transition equation
Example coins = [1, 2, 5]
1 The Title: amount = 11
, . It is easy to imagine:
The total amount 11
, according to the list of selected coins can [1, 2, 5]
be disassembled like this:
11 = 1 + (11 - 1)
: It represents11
is split into denominations of1
the coins and make up a face value of10
the number of coins and a minimum;11 = 2 + (11 - 2)
: It represents11
is split into denominations of2
the coins and make up a face value of9
the number of coins and a minimum;11 = 5 + (11 - 5)
: It represents11
is split into denominations of5
the coins and make up a face value of6
the number of coins and a minimum;
Three takes a minimum value. Write state transition equation below:
Here j
is a list of the number of coins. Note i - coins[j]
must be greater than or equal 0
, it makes sense.
In addition, please note: there are two very special status:
1 dp[0]
, 0
this denomination when a sheet is to be a reference value, if the total nominal value of 5, just have coins 5 of denominations is also, at this time dp[5] = 1 + dp[5 - 5] = 1
, it is provided dp[0] = 1
;
2, there may appear the case of Example 2, this time needs to be set dp[i] = - 1
, this question is asked a minimum, therefore, the initialization time can not be set 0
, it should be set to a large enough number.
Step 3: Initialize
(Above we have been discussed)
Step 4: Output
Output dp[amount]
can be.
Step 5: Can the state of compression
Each step may be used prior to the state, and therefore can not be compressed.
Remind ourselves again: Initialization of the time, because you want to compare is the minimum, and therefore can not be initialized . And here have a special meaning.
Java code:
import java.util.Arrays;
public class Solution {
public int coinChange(int[] coins, int amount) {
// 给 0 占位
int[] dp = new int[amount + 1];
// 注意:因为要比较的是最小值,这个不可能的值就得赋值成为一个最大值
Arrays.fill(dp, amount + 1);
dp[0] = 0;
for (int i = 1; i <= amount; i++) {
for (int coin : coins) {
if (i - coin >= 0 && dp[i - coin] != -1) {
dp[i] = Math.min(dp[i], 1 + dp[i - coin]);
}
}
if (dp[i] == amount + 1) {
dp[i] = -1;
}
}
if (dp[amount] == amount + 1) {
dp[amount] = -1;
}
return dp[amount];
}
}
You can use the "full backpack" template. (Code is correct, because I did not think was particularly clear.)
import java.util.Arrays;
public class Solution {
public int coinChange(int[] coins, int amount) {
int[] dp = new int[amount + 1];
Arrays.fill(dp, amount + 1);
dp[0] = 0;
for (int coin : coins) {
for (int i = coin; i <= amount; i++) {
dp[i] = Math.min(dp[i], dp[i - coin] + 1);
}
}
if (dp[amount] == 9999) {
dp[amount] = -1;
}
return dp[amount];
}
}
Note: 1, initialization time, a large number assigned to it, the maximum value of an int is likely to cause cross-border;
2, do not do print output in the code, slow down time.