1. 题目如下
2. 动态规划思路
动态规划的具体思路:
如上图 :
1. 第一层的dp(11)表示没有硬币加入
2. 第二层的1+dp(11-1)表示硬币1加入 (+1表示有一个硬币加入)
3. 第三层 得到dp(0)
实现上述方法, 我们要求出dp(1) dp(2) dp(3)…都等于多少就可以得到dp(11)的值
表格1:我们求出当只有硬币1 的时候dp(0)到dp(11)的所需的硬币个数
分别为
dp(1) 1个
dp(2) 2个
…
…
…
dp(11) 11个
详细计算看 表格2
0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | |
---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | 0 | Infinity | Infinity | Infinity | Infinity | Infinity | Infinity | Infinity | Infinity | Infinity | Infinity | Infinity |
1 | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 |
2 | 0 | |||||||||||
5 | 0 |
表格2: 这时我们有硬币1到各个dp(n)的所需硬币个数,此时算硬币2。
dp(1) 1 - 2 == -1 无法达到 得Infinity。 而硬币1到达dp(1)所需的硬币个数为1<Infinity,故可以延用dp(1)==1
dp(2) 2 - 2 ==0 可以达到,需要硬币的个数为dp(0)+1(+1表示,多了个硬币2),此时到达dp(2)的硬币数比原先小,则覆盖原先的值。
dp(3) 3 - 2 ==1 表示还需1元达到三元,而1元我们求出需要一个硬币,需要硬币的个数为dp(1)+1 ==2,比原来小覆盖。
…
…
以此类推得到 表格2 3
表格2
0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | |
---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | 0 | Infinity | Infinity | Infinity | Infinity | Infinity | Infinity | Infinity | Infinity | Infinity | Infinity | Infinity |
1 | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 |
2 | 0 | 1 | 1 | 2 | 2 | 3 | 3 | 4 | 4 | 5 | 5 | 6 |
5 | 0 |
表格3
0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | |
---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | 0 | Infinity | Infinity | Infinity | Infinity | Infinity | Infinity | Infinity | Infinity | Infinity | Infinity | Infinity |
1 | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 |
2 | 0 | 1 | 1 | 2 | 2 | 3 | 3 | 4 | 4 | 5 | 5 | 6 |
5 | 0 | 1 | 1 | 2 | 2 | 1 | 2 | 2 | 3 | 3 | 2 | 3 |
3. javascript算法
function coinChange(coins: number[], amount: number): number {
const dp: number[] = new Array(amount + 1).fill(Infinity);
dp[0] = 0;
for (let i = 1; i <= amount; i++) {
for (let j = 0; j < coins.length; j++) {
if (coins[j] > i) continue;
const a = dp[i - coins[j]] + 1;
dp[i] = Math.min(dp[i], a);
}
}
return dp[amount] === Infinity ? -1 : dp[amount];
}