劍指 Offer II 103. 最少的硬幣數目(動態規劃)
阿新 • • 發佈:2022-04-11
劍指 Offer II 103. 最少的硬幣數目
給定不同面額的硬幣coins
和一個總金額 amount
。編寫一個函式來計算可以湊成總金額所需的最少的硬幣個數。如果沒有任何一種硬幣組合能組成總金額,返回 -1
。
你可以認為每種硬幣的數量是無限的。
示例 1:
輸入:coins =[1, 2, 5]
, amount =11
輸出:3
解釋:11 = 5 + 5 + 1
示例 2:
輸入:coins =[2]
, amount =3
輸出:-1
示例 3:
輸入:coins = [1], amount = 0 輸出:0
示例 4:
輸入:coins = [1], amount = 1 輸出:1
示例 5:
輸入:coins = [1], amount = 2 輸出:2
提示:
1 <= coins.length <= 12
1 <= coins[i] <= 231 - 1
0 <= amount <= 104
動態規劃解法思路:
1、確定狀態:
1)最後一步(最優策略中使用的最後一枚硬幣ak),其中最後一枚硬幣ak可以為1、2、5;
2) 子問題(最少個數的硬幣拼出更小的面值11 - ak);
2、轉移方程:
f[x] = min(f[x -1] + 1, f[x -2] + 1, f[x - 5] + 1);
3、初始條件和邊界情況:
f[0] = 0,如果不能拼出y,f[y] = 正無窮;
4、計算順序:
f[0],f[1],f[2],... ...
1 class Solution { 2 public: 3 static constexpr int MAX_INF = 0x3F3F3F3F; 4 int coinChange(vector<int>& coins, int amount) { 5 int num = coins.size(); 6 vector<int> dp(amount + 1, MAX_INF); 7dp[0] = 0; 8 // 可以湊成總金額為i所需的最少硬幣個數為dp[i] 9 for (int i = 1; i <= amount; i++) { 10 // 選擇最後一枚硬幣 11 for (int j = 0; j < num; j++) { 12 if (i >= coins[j]) { 13 dp[i] = min(dp[i], dp[i - coins[j]] + 1); 14 } 15 } 16 } 17 return ((dp[amount] == MAX_INF) ? -1 : dp[amount]); 18 } 19 };