貪婪算法硬幣找零最優解問題證明


1. 問題

如果硬幣的面值是c0, c1, …, ck,則貪婪算法總是用最少的硬幣找零

 

2. 證明

2.1 一個硬幣的找零方式可以用如下公式來表示

m0c0 + m1c1 + … + mkck = S

mi = 每種面值的硬幣的數量(0, x)

ci = 硬幣的面值

根據題意 S = m0c0 + m1c1 + … + mkck

 

2.2 正面證明沒有合適的公式推導,因為貪婪算法沒有合適的公式表達,嘗試反證

假設有一種非貪婪算法的最優找零方案 S1 = m0c0 + m1c1 + … + mkck

貪婪算法的找零方案 S2 = n0c0 + n1c1 + … + nkck

假設從k開始,到x(x <= k)對應的面值的硬幣時,mx != nx

∵貪婪算法每次都講盡可能的使用最大面值的硬幣找零,所以nx > mx (因為S2的找零方案不同於S1,所以一定會有這么一個x滿足條件)

我們考慮最小情況,nx - mx = 1

1ck = c0 + (c-1)c0 + (c-1)c1 + … + (c-1)ck-1 > (c-1)c0 + (c-1)c1 + … + (c-1)ck-1

∵S1的找零方案中,m(m < k)不可能大於或等於c(當mx > c時,就可以將c個mx換成更高位的面值了,這樣硬幣數會減少)

∵S1 = m0c0 + m1c1 + … + mkck-1 <= (c-1)c0 + (c-1)c1 + … + (c-1)ck-1 < 1ck

∵S1中剩下的面值小於ck的硬幣面值總和不會大於一個ck的面值

∴ S1 != S2

∴ S1不存在,S2的貪婪算法是最優解

 

2.3 《離散數學及其應用》書中貪婪算法的反例

有面值1, 10, 25的硬幣,找零30。

貪婪算法的解:5c0 + 0c1 + 1c2 =  5*1 + 0*10 + 1*25 = 30,共需6枚硬幣

而最優解是:0c0 + 3c1 + 0c2 =  0*1 + 3*10 + 0*25 = 30,只需3枚硬幣

因為用3枚10面值的硬幣不能用任何25面值的硬幣和10面值的硬幣代替,所以換成高面值的硬幣不一定會使硬幣減少,所以2.2的證明無法在此應用

 

3. 擴展

從2.2的證明中可以看出,當貪婪算法是最優解時,只要cx = n*cx-1,2.2的證明同樣是成立的

所以硬幣的面值是k0c, k1c, …, knc時(如2, 10, 50)時,也是成立的


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM