剑指 Offer II 103. 最少的硬币数目(动态规划)
剑指 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 <= 121 <= coins[i] <= 231 - 10 <= 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); 7 dp[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 };
浙公网安备 33010602011771号