leetcode(动态规划)零钱兑换

https://leetcode-cn.com/explore/interview/card/top-interview-questions-medium/51/dynamic-programming/106/

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

示例 1:

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

示例 2:

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

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

动态规划(夏令营机试题有过这一题,我当时没复习动态规划,不会做,悔恨)

动态规划最关键的一点是想好dp数组的含义。

思路是从金额0到金额amount,每一步都力求计算出所需的最少硬币数dp[i],则最终dp[amount]就是凑齐金额amount所需最少的硬币数。

class Solution {
public:
    int coinChange(vector<int>& coins, int amount) {
        int dp[amount+1];//dp[i]代表凑够金额i所需最少的硬币数
        dp[0]=0;
        for(int i=1;i<=amount;i++)
        {
            int min=INT_MAX;
            for(int j=0;j<coins.size();j++)
            {//对于每个硬币,考虑在dp[i-coins[j]]最优的情况下再取这枚硬币,会不会是取得当前金额所需硬币最少
                
                if(i-coins[j]<0) continue;  //当前金额比coins[i]小,说明不可能取过一枚coins[i]
                if(dp[i-coins[j]]==INT_MAX) continue;//说明i-coins[j] 这个金额是之前没能凑不齐,因此跳过这个情况
                if(dp[i-coins[j]]+1<min)
                {
                    min=dp[i-coins[j]]+1;
                }
            }
            dp[i]=min;
        }
        if(dp[amount]==INT_MAX) {//说明没能凑齐
            return -1;
        }
        else 
            return dp[amount];
        
    }
};

猜你喜欢

转载自blog.csdn.net/weixin_41519463/article/details/88412773