假設 k=3 面值為 1 、 2 、 5 總金額 amount = 11 想要知道最少硬幣解法
static void Main(string[] args)
{
CoinChangeFuntion();
}
private static void CoinChangeFuntion()
{
var coins = new List<int>
{
1,
2,
5
};
int amount = 11;
Console.WriteLine(CoinChange(coins, amount));
}
private static int CoinChange(List<int> coins, int amount)
{
if (amount == 0) return 0;
int[] dp = new int[amount + 1];
Array.Fill(dp, int.MaxValue);
dp[0] = 0;
for (int i = 1; i <= amount; i++)
{
foreach (int coin in coins)
{
if (i - coin >= 0 && dp[i - coin] != int.MaxValue)
{
dp[i] = Math.Min(dp[i], dp[i - coin] + 1);
}
}
}
return dp[amount] == int.MaxValue ? -1 : dp[amount];
}
解題重點在於依序找出金額 0 ~ 11 最少的硬幣解法如下
註: dp[0] 裡面的 0 指的是金額
dp[0] = 0;
dp[1] = 1;
dp[2] = 1;
dp[3] = 2;
dp[4] = 2;
dp[5] = 1;
dp[6] = 2;
dp[7] = 2;
dp[8] = 3;
dp[9] = 3;
dp[10] = 2;
dp[11] = 3;
假設 i 是 11(表示我們目前正在嘗試組成金額 11),並且假設我們正在處理面值為 2 的硬幣。這時,i - coin 就是 11 - 2,等於 8。
這時候我們可以看 金額 dp[8] 最少的硬幣解法為 3 那 組成金額 11 最少的硬幣解法為 處理面值 2 (1枚硬幣) + 金額 8 元 (3枚硬幣) = 4 枚硬幣
當 for 迴圈中的 i 是 11(表示我們目前正在嘗試組成金額 11),並且假設我們正在處理面值為 5 的硬幣。這時,i - coin 就是 11 - 5,等於 6。
這時候我們可以看 金額 dp[6] 最少的硬幣解法為 2 那 組成金額 11 最少的硬幣解法為 處理面值 5 (1枚硬幣) + 金額 6 元 (2枚硬幣) = 3 枚硬幣
上述條件中 如果選擇面值為 2 的硬幣為 4 枚 選擇面值為 5 的硬幣為 3 枚 所以需要使用 Math.Min 取得最少硬幣數量
dp[i] = Math.Min(dp[i], dp[i - coin] + 1); 這行確保 dp[i](組成金額 i 所需的最少硬幣數量)是最小的可能值