有陣列penny,penny中所有的值都為正數且不重複。每個值代表一種面值的貨幣,每種面值的貨幣可以使用任意張,再給定乙個整數aim(小於等於1000)代表要找的錢數,求換錢有多少種方法。
經典的動態規劃問題,首先需要確定狀態,然後疊加即可。
首先確定初始狀態,當目標錢數為0時,無論如何只有一種方法,即不用任何面值的錢
當目標錢數小於面額最小的錢時,方法數為零
定義乙個二維陣列,i為所使用的面額index, j為目標錢數,我們需要按行來填滿這個陣列,陣列的最後乙個元素即為所求。
假設penny中共有,1,2,5三種面額錢數,需要湊齊100塊
res[0][0] 即為使用1塊錢,來湊齊0元,則只有一種方法,res[0][0]=1,res[0][1]同理也等於一,直到100,
res[1][0] 即為使用2塊錢來湊0元,則只有一種方法,不難看出,res[i][0]=1。這樣。我們就定義好了初始狀態,第一行全為1,第一列全為1
當求res[2][6]時,很顯然包括兩部分,首先,不使用當前的面額,只使用上一種面額,則為res[1][6],第二部分,當需要求使用當前面額時,問題就變成了用一張5塊以及若干1塊2塊來達到目標金額的方法也就是res[2][1]所以res[2][6]=res[1][6]+res[2][1]
總結上述規則可知,res[i][j]也就等於res[i-1][j]+res[i][j-penny[i]](此處需要說明一下為什麼只減去1次當前面額:有人會疑問如果我想用兩張當前面額呢?其實減去當前面額後,如果目標值仍大於當前面額,則所加上的res[i][j-penny[i]]在計算的時候,一定是res[i-1][j-penny[i]]+res[i][j-penny[i]-penny[i]]計算出來的,也就是說之前的已經包含了使用一張當前面額的情況,加上本次又一次使用當前面額,即使用兩張當前面額的情況,實際上已經算過了)
這樣得到了遞推公式,程式如下
class exchange
for(i=1;i=0) res[i][j]=res[i-1][j]+res[i][j-penny[i]]; //注意此處需要判斷,如果減去小於0的話,顯然不能用當前面額的紙幣
else res[i][j]=res[i-1][j];}}
return res[n-1][aim];}};
7 68 湊零錢 30分
輸入格式 輸入第一行給出兩個正整數 nnn 104 le 10 4 10 4 是硬幣的總個數,mmm 102 le 10 2 10 2 是韓梅梅要付的款額。第二行給出 nnn 枚硬幣的正整數面值。數字間以空格分隔。輸出格式 在一行中輸出硬幣的面值 v1 v2 vkv 1 le v 2 le cdot...
7 1 湊零錢 30分
8 9 5 9 8 7 2 3 4 1 1 3 5 4 8 7 2 4 3 no solution 動態規劃,先對硬幣價值公升序排序,從左向右依次選取硬幣,對於每個硬幣都有兩種情況,取或不取,當所取硬幣總額等於所需總額時,輸出 因為已經公升序排序,所得的第一組資料就是最小序列 以此進行遞迴。測試點6...
湊零錢問題 多種解法 遞迴 動態規劃
題 給你 k 種 值的硬幣,值分別為 c1,c2 ck 每種硬 幣的數量 限,再給 個總 額 amount 問你最少需要 枚硬幣湊出這個 額,如果不可能湊出,演算法返回 1。coding utf 8 created on wed mar 3 14 14 19 2021 author dujidan ...