力扣算法学习day29-2
先学习 完全背包理论
518-零钱兑换 II
题目
代码实现
class Solution {
public int change(int amount, int[] coins) {
// dp: 2ms 能够直接想到,但是是否完全理解各种细节的原因就不一定了。
// 很明显完全背包问题(因为硬币可以取多次),钱是重量,次数(方式)是价值。
// 1.创建dp数组,下标含义:dp[j] 表示 重量/面值j有几种组成方式
int[] dp = new int[amount+1];
// 2.确定迭代公式:dp[j] += dp[j-coins[i]]
// 3.初始化
dp[0] = 1;
// 4.确定遍历顺序,如下,如果是coins在外层可以,如果coins在内层,错误
// coins = 1 1,1,1,1,1,1
// coins = 2 1,1,2,2,3,3
// coins = 5 1,1,2,2,3,4
// j = 1, 1,1,0,0,0,0
// j = 2, 1,1,2,0,0,0 11,2
// j = 3, 1,1,2,3,0,0 111,21,12
// j = 4, 1,1,2,3,5,0
// j = 5 1,1,2,3,5,9
// 原因:因为次数是相当于背包问题需要求的价值,但是次数应该是组合问题,如果j在外层的话,那么每个j
// 都会遍历所有硬币,那么就会出现组合相同但是顺序不同的情况,这就会导致次数统计比预计的多了。
for(int i = 0;i < coins.length;i++){
for(int j = coins[i];j < dp.length;j++){
dp[j] += dp[j-coins[i]];
// System.out.print(dp[j]);
}
// System.out.println();
}
return dp[amount];
}
}