【程式碼隨想錄】零錢兌換

SaTsuki26681534發表於2024-03-23

題目描述

image

分析

這道題分析起來並不難。遞推公式也能分析出來,但是我當時寫的時候疑惑的一個問題就是:如何判斷硬幣組合的總額剛好等於需要的金額,因為這裡的dp陣列很明顯是組成總金額所需的最少硬幣個數。
我試著加了一個陣列儲存當前情況下的金額。但是想一下就知道這樣太笨了。實現起來也特別困難。
首先看一下程式碼隨想錄的程式碼:

class Solution {
public:
    int coinChange(vector<int>& coins, int amount) {
        vector<int> dp(amount + 1, INT_MAX);
        dp[0] = 0;
        for (int i = 0; i < coins.size(); i++) { // 遍歷物品
            for (int j = coins[i]; j <= amount; j++) { // 遍歷揹包
                if (dp[j - coins[i]] != INT_MAX) { // 如果dp[j - coins[i]]是初始值則跳過
                    dp[j] = min(dp[j - coins[i]] + 1, dp[j]);
                }
            }
        }
        if (dp[amount] == INT_MAX) return -1;
        return dp[amount];
    }
};

它透過把dp陣列的初始值設定為INT_MAX,並在遍歷中設定條件if (dp[j - coins[i]] != INT_MAX)。
dp[0]設定為0是因為從0開始組合,也就是j == coins[i]的話,肯定能形成一種組合,而如果dp[j - coins[i]]為INT_MAX的話,就說明這個位置沒有被修改過,也就是說沒有一種組合的總金額剛好等於j,透過這種機制就能判斷出組合總額湊不齊總金額的情況。
在最後返回的時候也能看出來,如果do[amount]為INT_MAX的話,就返回-1,代表沒有組合的總額能等於amount

相關文章