LeetCode-322. 零钱兑换

小咪咪 2022-01-27 00:25 357阅读 0赞

322. 零钱兑换

给定不同面额的硬币 coins 和一个总金额 amount。编写一个函数来计算可以凑成总金额所需的最少的硬币个数。如果没有任何一种硬币组合能组成总金额,返回 -1。

示例 1:

  1. 输入: coins = [1, 2, 5], amount = 11
  2. 输出: 3
  3. 解释: 11 = 5 + 5 + 1

示例 2:

  1. 输入: coins = [2], amount = 3
  2. 输出: -1

说明:
你可以认为每种硬币的数量是无限的。

dp

dp[x]表示总金额为x兑换零钱需要的最少硬币数。
状态转移方程:dp[i] = min(dp[i],dp[i - coins[j]] + 1)

  1. class Solution {
  2. public:
  3. int coinChange(vector<int>& coins, int amount) {
  4. int n = coins.size();
  5. vector<int> dp(amount + 1,INT_MAX); // dp[i]表示总金额为i兑换需要的最少硬币数
  6. dp[0] = 0;
  7. for(int i = 1; i <= amount; i++) {
  8. for(int j = 0; j < n; j++) {
  9. if(i - coins[j] >= 0 && dp[i - coins[j]] < INT_MAX) {
  10. dp[i] = min(dp[i],dp[i - coins[j]] + 1);
  11. }
  12. }
  13. }
  14. if(dp[amount] < INT_MAX)
  15. return dp[amount];
  16. return -1;
  17. }
  18. };

dfs+剪枝

将硬币面额从大到小枚举,优先输出最优解。

  1. class Solution {
  2. public:
  3. // s表示当前硬币面额下标,cur表示当前硬币数,nums当前未兑换剩余面额,ans最优解
  4. void dfs(vector<int> &coins,int s,int cur,int nums,int &ans) {
  5. if(s < 0) return;
  6. if(nums % coins[s] == 0) {
  7. ans = min(ans, cur + nums/coins[s]);
  8. return;
  9. }
  10. for(int i = nums/coins[s]; i >= 0; i--) { // 枚举用该面额硬币数
  11. if(cur + i >= ans) break; // 剪掉不合理的解
  12. dfs(coins, s - 1,cur + i, nums - i * coins[s], ans);
  13. }
  14. }
  15. int coinChange(vector<int>& coins, int amount) {
  16. int len = coins.size();
  17. int ans = INT_MAX;
  18. sort(coins.begin(),coins.end());
  19. dfs(coins, len - 1, 0, amount, ans);
  20. if(ans < INT_MAX) return ans;
  21. return -1;
  22. }
  23. };

发表评论

表情:
评论列表 (有 0 条评论,357人围观)

还没有评论,来说两句吧...

相关阅读

    相关 leetcode 322 零钱兑换

    给定不同面额的硬币 coins 和一个总金额 amount。编写一个函数来计算可以凑成总金额所需的最少的硬币个数。如果没有任何一种硬币组合能组成总金额,返回 -1。 示例 1

    相关 leetcode322 零钱兑换

    给定不同面额的硬币 coins 和一个总金额 amount。编写一个函数来计算可以凑成总金额所需的最少的硬币个数。如果没有任何一种硬币组合能组成总金额,返回 -1。 示例 1

    相关 322. 零钱兑换

    > 给定不同面额的硬币 coins 和一个总金额 amount。编写一个函数来计算可以凑成总金额所需的最少的硬币个数。如果没有任何一种硬币组合能组成总金额,返回 -1。 >

    相关 Leetcode 322. 零钱兑换

    题目重述 给你一个整数数组 coins ,表示不同面额的硬币;以及一个整数 amount ,表示总金额。 计算并返回可以凑成总金额所需的 最少的硬币个数 。如果没有任何

    相关 LeetCode-322. 零钱兑换

    [322. 零钱兑换][322.] 给定不同面额的硬币 coins 和一个总金额 amount。编写一个函数来计算可以凑成总金额所需的最少的硬币个数。如果没有任何一种硬币