1. 程式人生 > >leetcode322 Coin Change (動態規劃之 湊錢問題 - 1)

leetcode322 Coin Change (動態規劃之 湊錢問題 - 1)

湊錢問題可以說是一類非常經典的演算法了, 也就是給你一堆相應面額的錢幣, 要求用最少的錢幣數湊出一個數, 通常會用貪心和動態規劃兩種演算法

用貪心演算法的情況一般只有一種, 就是各個面額之間沒有公因子的情況, 比如人民幣, 就分為1, 5, 20, 50, 100; 這樣的話每次就儘量取最大的就好了

可如果像這道題一樣, 面額是隨機輸入的, 比方說我輸入的是2, 3那麼湊的話就不能按照貪心來湊了

就必須要用到動態規劃, 其實這題本身就是一個動態規劃中的完全揹包問題 (即每一個硬幣可以取無限次), 可以參考我寫的完全揹包題解: https://blog.csdn.net/a1097304791/article/details/83547276

是揹包問題就要考慮到對容量的定義, 很顯然只能是金額作為容量

注意由於是取最小的數, 所以除了dp[0]之外應該初始化為1<<30

class Solution {
public:
    int coinChange(vector<int>& coins, int amount) {
        if(amount < 0) return -1;
        else if(amount == 0) return 0;
        
        int dp[amount+5]; //湊成i元時的最少硬幣數
        dp[0] = 0;
        for(int i = 1; i <= amount; i++)
            dp[i] = 1<<30;
        
        for(int j = 0; j < coins.size(); j++)
            for(int i = 1; i <= amount; i++){
                if(i >= coins[j])
                    dp[i] = min(dp[i], dp[i-coins[j]]+1);
            }
        
        if(dp[amount] > amount) return -1; //特殊條件
        return dp[amount];
        
    }
};