
思路:动态规划
- 完全背包
- dp[j]:凑成总金额j的货币组合数为dp[j]
- 递推公式:
dp[j] += dp[j - coins[i]]
;
dp[j]
(凑成总金额j的货币组合数) 就是所有的dp[j - coins[i]]
(i变化)相加。
- 比如,凑5块钱的方法数 = 凑4块钱的方法数(再选一元硬币)+ 凑3块钱的方法数(再选2元硬币) + 凑0块钱的方法数(再选5元硬币)
- dp数组初始化
- 首先
dp[0]一定要为1
,从dp[i]
的含义上来讲就是,凑成总金额0的货币组合数为1。
- 下标非0的
dp[j]
初始化为0,这样累计加dp[j - coins[i]]
的时候才不会影响真正的dp[j]
- 由于本题找组合数,所以外层循环要遍历物品,内层遍历背包容量,不可更换。 如果外层遍历背包容量,求出来的是排列数。
- 外层遍历coins:假设:coins[0] = 1,coins[1] = 5。那么就是先把1加入计算,然后再把5加入计算,得到的方法数量只有{1, 5}这种情况。而不会出现{5, 1}的情况。
- 外层遍历amount:背包容量的每一个值,都是经过 1 和 5 的计算,包含了{1, 5} 和 {5, 1}两种情况。
class Solution {
public int change(int amount, int[] coins) {
int length = coins.length;
int[] dp = new int[amount + 1];
dp[0] = 1;
for (int i = 0; i < length; i++) {
for (int j = 1; j <= amount; j++) {
if (j - coins[i] >= 0) {
dp[j] = dp[j] + dp[j - coins[i]];
}
}
}
return dp[amount];
}
}
