題解 零錢兌換

2022-10-11 14:15:12 字數 2126 閱讀 1432

give me your money!!1

step1:觀察題面,這可以讓我們了解題的型別。

「編寫乙個函式來計算可以湊成總金額」,可以得出這是一道揹包 dp

「每種硬幣的數量是無限的」,進一步得出這是道完全揹包。(題型:完全揹包)

最少的硬幣個數」,證明這要在揹包的前提下,求出最小組成數量。

多組測試資料」,謹記多組輸入 (論wrong answer與沒有多組輸入)。(注意:多組輸入)

step2:思考解法。

第一步,思考 dp 狀態:

\(dp_\):前 \(i\) 種硬幣湊出面值 \(j\) 的最少幣數。

對於當前一種硬幣 \(coins_\) 而言,只有取或不取兩種狀態。

,取後的幣數為前 \(i - 1\) 種硬幣湊出面值 \(j-w_\times k\) 的總幣數加上當前種類所需幣數 \(k\)。

不取,則說明前 \(i - 1\) 種硬幣已經能夠湊出面值 \(j\),不需要再取。

第二步,思考狀態轉移方程:

原本完全揹包的狀態轉移方程是:

\[dp_ = \max\, dp_}+a_\}\ (a_\le j\le amount)

\]但這裡我們並不是求總金額以內最大能湊出的面值,而是求湊成總金額的最少幣數,於是就有:

\[dp_=\min\,\,dp_} + 1\}\ (a_\le j\le amount)

\]通過觀察發現,上述方程可以降維。由於對 \(dp_\) 有影響的只有 \(i - 1\),故可以把前一維抹掉,但需要保證 \(dp_\) 可以被 \(dp_}\) 影響(即 \(dp_\) 被計算時 \(dp_}\) 已經被算出),這才相當於物品 \(i\) 多次被放入揹包,所以列舉當前面值 \(j\) 時要正序。

第三步,打出完全揹包的**,把狀態轉移方程換一下,於是本題的演算法部分就完成啦:

for (int i = 1; i <= n; i++) 

}

step3:完成**:

通過資料範圍可以發現,一種硬幣的面額是可以比總金額大的,因此可以預處理淺淺優化一下(雖然沒什麼大的效果)。

因為找的是最小幣數,所以 dp 陣列要初始化成極大值,而前 \(0\) 種硬幣湊成 面值 \(0\) 只需要 \(0\) 種硬幣,由此可得 \(dp_ = 0\)。

輸出時值得注意的是,「如果沒有任何一種硬幣組合能組成總金額,輸出 \(-1\)」;在**中,這意味著「如果 \(dp_\) 沒有被更新,則輸出 \(-1\)」,所以只需要輸出時特判一下 \(dp_\) 若仍是初始值就輸出 \(-1\)。

\**(抵制學術不端行為,拒絕 ctrl + c):

#include using namespace std;

const int n = 1e2 + 5, a = 1e4 + 5, inf = 0x3f3f3f3f;

int n, amount, a[n], dp[a];

/* dp(i, j): 前 i 個硬幣湊出 j 的最少硬幣個數

dp(i, j) = min(dp(i - 1, j - a[i]), dp(i - 1, j));

取這個硬幣 or 不取這個硬幣

*/int main()

dp[0] = 0;

for (int i = 1; i <= n; i++)

}printf("%d\n", dp[amount] == inf ? -1 : dp[amount]); // 可以使用三目運算子來特判

}return 0;

}

快去 ac 『零錢兌換』 叭~ ヾ(≧▽≦*)o

bye bye!

Leetcode題解 零錢兌換

注 用揹包問題思想來理解硬幣找零系列問題 for c in coins 列舉硬幣總數 for j in range m,c 1,1 從大到小列舉金額,確保j c 0.f j min f j f j c 1 return f m if f m float inf else 1 如果為inf說明狀態不可...

零錢兌換 leetcode

思路 建乙個動態陣列dp,大小為amount 1,dp裡面的值初始化為amount 1。dp i 表示總金額i最少可以用dp i 的零錢兌換,如果coins j 比i小,那麼總金額i可以由dp i conis j 再加上這枚零錢構成,dp i min dp i dp i coins j 1 如果dp...

leedcode 零錢兌換

給定不同面額的硬幣 coins 和乙個總金額 amount。編寫乙個函式來計算可以湊成總金額所需的最少的硬幣個數。如果沒有任何一種硬幣組合能組成總金額,返回 1。示例1輸入 coins 1,2,5 amount 3 輸出 3 解釋 11 5 5 1示例2輸入 coins 2 amount 3 輸出 ...