最少找零問題描述如下,有n張硬幣,價值儲存在乙個陣列中,每種硬幣個數都是無限的,再給定乙個要找的零錢數,然後試用最少的數目的硬幣來找我們要求的數目。
比如 5,2,3,要找出20元錢,我們人工的判斷幾個可能,很快就可以找出最優,也就是4張5元,也就是4.
如果這個題目要求用程式解決,我們可以遵循如下思路
首先如果全部用5元,則其最多4張,如果全部用2元,則最多是10張,如果全部3元,最多6張(如果是7張,則大於20元),所以我們可以使用暴力遞迴來判斷,在0張5元,0張2元,0張3元, 或者0張5元,0張2元,1張3元,或者0張5元,0張2元,2張3元·······
以錢幣金額為標準,其呼叫的數目**如下,
5 2 3
0 0 0
0 0 1
0 0 2
0 0 3
0 0 4
0 0 5
0 0 6
0 1 0
0 1 1
0 1 2
0 1 3
0 1 4
0 1 5
0 1 6
0 2 0
0 2 1
0 2 2
0 2 3
0 2 4
0 2 5 (這裡3元金額的數目為5,而沒有到6,是因為前面呼叫了0張5元,2張2元,這是剩餘金額為20-2*2=16元,最多需要5張)
0 3 0
從以上**可以看到在標註的地方,選擇了0張5元,2張2元,5張3元,這時候還剩1元,這個需要我們考慮,如果多了1元,該如何處理。
如果做過揹包問題的多重揹包問題,必然知道這個題目的模型和多重揹包是很類似的,乙個深度搜尋,在下標到達邊界時候,返回乙個值,但是多重揹包返回的是0,而且多重揹包完全不會考慮你裝完最後乙個物品後, 你的揹包容量還剩幾個單元,是正好裝滿,還是差幾個單元,它只關注他的總體最大價值,而這個題和完全揹包問題的區別在於,這個題需要判斷,我們在遞迴到邊界的時候,「揹包」的容量還有多少,如果前面選擇了x個5元,y個2元,z個3元,這時候再遞迴到邊界時候,「揹包」剩餘容量是0,代表前面的這些組合正好組成了我們需要的金錢數目,這時候需要返回什麼?同樣如果前面選擇了x個5元,y個2元,z個3元,這時候再遞迴到邊界時候,「揹包」剩餘容量不是0,代表前面的組合沒有組成我們要的數目,還差幾塊錢,這時候,要返回什麼?
很明顯,面對第乙個問題,我們只需要返回0就可以了,然後前面的硬幣數目(比如 x y z)加上返回值,就可以返回其組合數。
面對第二個問題,我們可以用乙個例子來看看
5 2 3
0 4 0 -----> 要給前面返回乙個比較大的值
0 4 1 -----> 要給前面返回乙個比較大的值
0 4 2 -----> 要給前面返回乙個比較大的值
0 4 3 -----> 要給前面返回乙個比較大的值
0 4 4
0 5 0
0 5 1
0 5 2
上面是幾組資料, 對於前四組,我們口算就可以得知其都不可以組合成20,遞迴到邊界時候,要返回乙個值,返回誰?如果是0,肯定是錯誤的,我們可以返回乙個比較大的值,比如#define maxsize 10010,返回這個maxsize,往下走,在0 4 4 時候,正好可以組合成20元,返回0,然後0+4+4+0(相加順序是從後往前的,因為遞迴本來就是從後往前回溯的)=8,對於0張5元,4張2元,我們可以得到5個返回值,分別是 maxsize, maxsize, maxsize, maxsize,8,我們找到這裡面最小的8,就可以結束(0,4,x)這個遞迴了,後面也都是一樣。
總結下,如果遞迴到邊界時候,剩餘硬幣數目為0,也就是剛剛好,要返回0,如果是非0,則返回乙個預定義的乙個較大值,**如下。
#include #include #include #include using namespace std;
#define maxsize 10010
int arr[100]=;
int fun(int arr,int index,int aim)
if(aim<=0)
for(int i=0;i*arr[index]<=aim;i++)
return ret;
}int main()
{ if(maxsize==fun(arr,0,2))
{ cout<<0<
nyoj995硬幣找零完全揹包
時間限制 1000 ms 記憶體限制 65535 kb 難度 3 描述 在現實生活中,我們經常遇到硬幣找零的問題,例如,在發工資時,財務人員就需要計 算最少的找零硬幣數,以便他們能從銀行拿回最少的硬幣數,並保證能用這些硬幣發工資。我們應該注意到,人民幣的硬幣系統是 100,50,20,10,5,2,...
NYOJ 995 硬幣找零 完全揹包
時間限制 1000 ms 記憶體限制 65535 kb 難度 3 描述 在現實生活中,我們經常遇到硬幣找零的問題,例如,在發工資時,財務人員就需要計 算最少的找零硬幣數,以便他們能從銀行拿回最少的硬幣數,並保證能用這些硬幣發工資。我們應該注意到,人民幣的硬幣系統是 100,50,20,10,5,2,...
動態規劃,0 1揹包,完全揹包 找零錢),套路
動態規劃問題的一般形式就是求最值。求解動態規劃的核心問題是窮舉。動態規劃的窮舉有點特別,因為這類問題存在 重疊子問題 如果暴力窮舉的話效率會極其低下,所以需要 備忘錄 或者 dp table 來優化窮舉過程,避免不必要的計算。而且,動態規劃問題一定會具備 最優子結構 才能通過子問題的最值得到原問題的...