1.Dynamic Programming先建表,再從小答案推大答案
amount = 5 要記:
dp[0] 湊 0 元最少幾枚
dp[1] 湊 1 元最少幾枚
dp[2]
dp[3]
dp[4]
dp[5]
共 6 格 = amount + 1 格。
2.第二個也先填 amount + 1 因為一開始:dp[1]、dp[2]...dp[5]都還不知道答案,不能先放 0,不然 0 會被誤認成「0 枚就能湊出來」。所以用超出表示「目前不知道 / 湊不到」最後再:dp[0] = 0;
因為只有「0 元需要 0 枚」是一開始確定知道的答案。
記憶:amount+1 格 = 0~amount;全部先放「未知」,只有 dp[0]=0 是起點。
currentAmount = 5 ; coin = 2
最後一枚硬幣決定用 2,那前面還要湊多少?5 - 2 = 3
之前都算好了dp[3] = 湊 3 元最少幾枚;假設:dp[3] = 2;dp[3] + 1
= 前面湊 3 元的 2 枚+ 現在這枚 2 元= 3 枚
「剩下的金額最佳答案」+「現在這枚 coin」。
前面的最佳答案已經算好了,現在只要再加這一枚 coin。
4.for (int coin : coins) 從右coins一個一個拿出來,放到左邊目前這個 coin。
5.coins = [1,2,5];currentAmount = 5
就依序試:
coin = 1 → 看 dp[4] + 1
coin = 2 → 看 dp[3] + 1
coin = 5 → 看 dp[0] + 1
最後挑最小
6.目前金額 currentAmount
→ 拿一枚 coin
→ 扣掉 coin
→ 剩下 currentAmount - coin
→ 回頭查 dp[currentAmount - coin]
→ 再 +1(把剛拿的這枚 coin 算回來)