码迷,mamicode.com
首页 > 编程语言 > 详细

某种 找换硬币问题的贪心算法的正确性证明

时间:2016-06-11 17:30:46      阅读:709      评论:0      收藏:0      [点我收藏+]

标签:

一,问题介绍

最近一直在看贪心算法的正确性证明(如何证明贪心算法获得的解一定是最优解),感觉“剪枝”技巧用得比较多。再看了下《算法导论》中贪心算法一章里面的一个练习---找换硬币问题。这个问题对于某些 面值的硬币 是有最优解的,故记录下其中的一些证明思路。

考虑用最少的硬币数 来找 n 分钱的问题,假设每个硬币的值都是整数。

如果可换的硬币的单位是 c 的幂,也就是 c0,c1,... ,ck ,其中整数 c>1,k>=1

证明贪心算法总可以产生一个最优解。

 

二,找换硬币的贪心策略

这里的贪心策略很容易想到:总是优先选择 大面值的硬币 去找。比如,现有 1分、5分、10分、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

下面给出正确性证明。

 

三,找换硬币的贪心算法的正确性证明

在进行证明之前,先提一个性质:对于最优解而言,如果使用了面值为 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背包问题区别

 

某种 找换硬币问题的贪心算法的正确性证明

标签:

原文地址:http://www.cnblogs.com/hapjin/p/5575112.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!