1. 問題
如果硬幣的面值是{1, 1*c, 2*c, …, k*c}, 則貪婪算法總是用最少的硬幣找零。
如《離散數學及其應用》書中貪婪算法的反例:
有面值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枚硬幣
但如果補齊中間缺失的硬幣面值:{1, 5, 10, 15, 25},
那么貪婪算法的解是 : 1*25 + 1*5 = 30,只需2枚硬幣,依然是最優解之一(因為還有15*2也是最優解)
2. 規律
因為最大的25面值的硬幣不再滿足《貪婪算法最優解問題》問題中的條件,所以無法用該證明方法證明,思路不通時我們先找找滿足問題條件的找零方案,看能不能找出一些規律,然后再證明這些規律找出一些推論來間接證明
假設有面值{1, 3, 6, 9}的硬幣,當需找零S的最優貪婪算法找零方案:
1 | 3 | 6 | 9 | |
9 | 1 | |||
10 | 1 | 1 | ||
11 | 2 | 1 | ||
12 | 1 | 1 | ||
13 | 1 | 1 | 1 | |
14 | 2 | 1 | 1 | |
15 | 1 | 1 | ||
16 | 1 | 1 | 1 | |
17 | 2 | 1 | 1 | |
18 | 2 |
從表中可以看出:
1> 除了最大面值和1面值的硬幣以外,其他面值的硬幣最多只有1個
2> 1面值的硬幣最多只有2個
3. 推論證明
3.1 除了最大面值和1面值的硬幣以外,其他面值的硬幣最多只有1個
最優找零公式:S = m01 + m11c + m22c + … + mkkc
S = m01 + (m11 + m22 + … + mkk)c = m01 + gc = m0 + gc (m0 < c, g >= 0)
從公式中,我們可以自覺感受到S中,一定有m0個面值為1的硬幣,但從嚴謹的數學邏輯出發,我們還是證明一下
3.2 假設最優找零公式 S = m0 + gc (m0 < c, g >= 0),有另一種最優找零公式 S1 = x + hc (x < c, x != m0, g >= 0)
m0 + gc = x + hc
(m0 - x) = (h-g)c 或(x -m0) = (g-h)c (2個形式的證明都是一樣的)
∵x != m0
∴(h-g)c != 0
∴(m0 - x) = nc (n > 0)
∴m0 = nc + x > c (n > 0)
∵m0大於c時,一定可以將c個m0轉化為一個面值為c的硬幣,轉化后的總數量必然小於m0
∴m0 = nc + x不成立,假設不成立
∴最優找零公式S中,一定有m0個面值為1的硬幣
3.3 已知S中m0數量固定,所以只要找出S = gc 的最優找零數量,即是S的最優找零方案,我們先嘗試找一找各種情況下的方案
S = gc = (m11 + m22 + … + mkk)c
去掉c, g = m11 + m22 + … + mkk
3.3.1 當g <= k時,g = x (x∈{1, 2, …, k}),用一枚面值x的硬幣即是最優解
3.3.2 當k< g <= 2k時,g = k + x (x∈{1, 2, …, k}),只需2枚硬幣即可,因為1枚硬幣最多只能表達到k的面值,而g > k,所以g = g = k + x即是最優解
3.3.3 當2k< g <= 3k時,g = 2k + x (x∈{1, 2, …, k}),只需3枚硬幣即可,因為用2枚硬幣最多只能表達到2k的面值,而g > 2k,所以g = 2k + x即是最優解
也就是說,對於任意一個g,總是可以表達為 g = nk + x 這種形式(如我們所有的數都可以用 (n10 + x)(0<= n, 0< x < 10)來表示),且這種形式的找零方案是最優的(使用n + 1枚硬幣)
3.4 證明,g = m11 + m22 + … + mkk = nk + x (0 < x < k) 時,沒有一種其他的找零方案使用的硬幣數 <= n
反證,假設有一種找零方案g1 = m11 + m22 + … + mkk,使用的硬幣數 <= n
∵n枚kc面值的的硬幣總數總是大於或等於n枚由{1c, 2c, …, kc}組成的硬幣總數
∴g1 <= nk < nk + x = g
∴g1 != g
∴不存在這一的找零方案g1
∴g = nk + x這樣的找零方案總是最優的
∴g總是用最大數量的k,和一枚其他數量的x去找零,這完全滿足貪婪算法的找零方案
∴S = gc 的最優找零數量是貪婪算法
∴S = m0 + gc 的最優找零方案是貪婪算法