一,問題介紹
最近一直在看貪心演算法的正確性證明(如何證明貪心演算法獲得的解一定是最優解),感覺「剪枝」技巧用得比較多。再看了下《演算法導論》中貪心演算法一章裡面的乙個練習---找換硬幣問題。這個問題對於某些 面值的硬幣 是有最優解的,故記錄下其中的一些證明思路。
考慮用最少的硬幣數 來找 n 分錢的問題,假設每個硬幣的值都是整數。
如果可換的硬幣的單位是 c 的冪,也就是 c0,c1,... ,ck ,其中整數 c>1,k>=1
證明貪心演算法總可以產生乙個最優解。
二,找換硬幣的貪心策略
這裡的貪心策略很容易想到:總是優先選擇 大面值的硬幣 去找。比如,現有 1分、5分、25分的硬幣可用來找錢,現在我們需要找 n=32分 的零錢,如何找?
優先選擇大面值的嘛,那就是先選 25分;選完之後,還要找32-25=7,那就再選5分的,最終再先2個1分的。即可。
這裡:32=25+5+1+1,一共用了4枚硬幣。那麼,問題來了!!!還有沒有其他策略 只需要 3 枚硬幣?或者更少的硬幣?
這就需要證明貪心策略 有沒有 最優解了?對於這個問題而言,如果用來找換的硬幣的 面值滿足某種性質,該貪心策略是有最優解的。
這裡說的某種性質就是:可換的硬幣的單位(或者稱 面值)是 c 的冪,也就是 c0,c1,... ,ck ,其中整數 c>1,k>=1
下面給出正確性證明。
這裡需要強調一點: 硬幣面值滿足上面的性質時貪心演算法一定能產生最優解,但是不滿足時,也有可能有最優解。比如,面值為1,5,10,20,50,100時,貪心找零也一定有最優解。
三,找換硬幣的貪心演算法的正確性證明
在進行證明之前,先提乙個性質:對於最優解而言,如果使用了面值為 ci 的硬幣去找零,那麼 ci 最多只能使用 c-1 個。
因為我們的目標是使用 最少數目的硬幣,對於最優解而言,如果使用了面值為 ci 的硬幣去找零,那麼 ci 最多只能使用 c-1 個。
why?假設使用了c 個
(大於c個也一樣)面值為 ci 的硬幣去找零,那我為什麼不用乙個
面值為 ci+1 的硬幣去找呢?
這樣,我就可以用更少的硬幣數啊(c>1)。所以說,在最優解裡面,如果使用了面值為 ci 的硬幣去找零,那麼 面值為ci 的硬幣 最多只能使用 c-1 個。
ok,下面再次用到剪枝的思想來證明貪心選擇的正確性了。
總體思路是:先考察乙個最優解,然後證明可對該解進行修改,使其採用貪心選擇,這個選擇將原問題變成乙個相似的、但是「更小」的問題。(這裡說的「更小」是一種抽象,並不是具體意義上的更小)
k 是可找換的硬幣的種類數,n 是需要找換的價值,a(i)表示使用多少個 面值為 ci 的硬幣。假設硬幣已經按面值從小到大排序。
對於貪心選擇而言,我們一定會選擇面值為 c^j 的硬幣,因為:我們的貪心策略就是總是優先選擇 面值最大的硬幣。
我們的目標是證明,對於所有的非貪心選擇而言,它們都不可能產生最優解。
對於非貪心選擇,是不會選擇 面值為 c^j (or higher)的硬幣的。非貪心選擇使用的硬幣如下:
其中,a(i)表示使用了 a(i)個 面值為 ci 的硬幣,總數之和是n。別忘了,n 就是需要找零的數目
而對於貪心選擇而言,如果面值為 c^j 的硬幣可用(當 n>=c^j 時),我們是優先使用 面值為 c^j 的硬幣的。
因此有:
這說明,在面值為 c^j 的硬幣 可用的情況下,換句話說:在 c^j <=n 的情況下,非貪心選擇沒有使用 c^j 嘛。(選擇了的話,那就是貪心選擇了嘛...~)
這裡就會有矛盾了,根據前面提到的性質:有, a(i) <= c-1
從而,證明了貪心選擇的正確性。
再來理解下它:總體思路是:先考察乙個最優解,然後證明可對該解進行修改,使其採用貪心選擇,這個選擇將原問題變成乙個相似的、但是「更小」的問題。(這裡說的「更小」是一種抽象,並不是具體意義上的更小)
這裡的最優解是:非貪心選擇下的某個最優解,然後剪枝:將非貪心選擇下的某個元素去掉,然後添入貪心選擇的那個元素。其實就是下面的這個公式。
從而得到了乙個更優的問題。
四,參考資料
部分揹包問題的貪心演算法正確性證明
某種 找換硬幣問題的貪心演算法的正確性證明
從 活動選擇問題 看動態規劃和貪心演算法的區別與聯絡
找換硬幣問題的求解 以及與 0-1揹包問題區別
硬幣問題(典型的貪心演算法)
有1元,5元,10元,50元,100元,500元的硬幣各c1 c5 c10 c50 c100 c500 枚。現在要用這些硬幣來支付a 元,最少需要多少枚硬幣?假設本題至少存在一種支付方案。限制條件 0 c1 c5 c10 c50 c100 c500 100000000000 0 a 10000000...
程式設計 貪心演算法解決硬幣問題
問題描述 有1元 5元 10元 50元 100元 500元的硬幣各c1,c5,c10,c50,c100,c500枚。現在要用這些硬幣來支付a元,最少需要多少枚硬幣?假設本題至少存在一種支付方案。限制條件 0 c1,c5,c10,c50,c100,c500 10的9次方 0 a 10的9次方 輸入 c...
貪心演算法 硬幣問題(無限個)
貪心演算法 又稱貪婪演算法 是指,在對問題求解時,總是做出在當前看來是最好的選擇。也就是說,不從整體最優上加以考慮,演算法得到的是在某種意義上的區域性最優解 1 貪心演算法不是對所有問題都能得到整體最優解,關鍵是貪心策略的選擇。也就是說,不從整體最優上加以考慮,做出的只是在某種意義上的區域性最優解。...