画圆的沙滩

亦简亦美

买书问题

编程之美1.4节。这是一道很有趣的问题。作者试图使用贪心策略去解答,尽管给出了贪心中关键的变化,不过最终并没有给出证明。然后,解法二中使用了动态规划来求解这道题。另外,新版中提到薛笛有更细致一点的分析:http://blog.csdn.net/kabini/archive/2008/04/16/2296943.aspx,其中主要讨论了贪心算法。不过,我感觉仍然不够简明清晰。

确实,这道题是可以使用贪心的。关键是如何应用贪心策略,从而保证可以到达最优解。下面给出我的理解。

首先,类似于作者的思路,可以试图分解较小的数找到最佳的分解组合。不过,这里作者和薛笛关注的方向不恰当。事实上,对于任意的组合数,我们最终都要将它们分解成为不超过5的数字的和。假设我们采用贪心法获得了第一种组合。比如作者举例的(7,6,5,3,2),获得这样的初始结果:

 (7,6,5,3,2) = 5 + 5 + 4 + 3 + 3 + 2 + 1

                  =(1,1,1,1,1) + (1,1,1,1,1) + (1,1,1,1,0) + (1,1,1,0,0) + (1,1,1,0,0) + (1,1,0,0,0) + (1,0,0,0,0)

已经知道,这样并不能获得最优的解。它并不是最优是因为在折扣上 5 + 3 < 4 + 4。我们考虑所有两两和的组合优势表:

1: 1 + 0 (0.0)

2: 2 + 0 (0.1) > 1 + 1 (0.0)

3: 3 + 0 (0.3) > 2 + 1 (0.05)

4: 4 + 0 (0.8) > 3 + 1 (0.3) > 2 + 2 (0.1)

5: 5 + 0 (1.25) > 4 + 1 (0.8) > 3 + 2 (0.4)

6: 5 + 1 (1.25) > 4 + 2 (0.9) > 3 + 3 (0.6)

7: 5 + 2 (1.35) > 4 + 3 (1.1)

8: 4 + 4 (1.6) > 5 + 3 (1.55)

9: 5 + 4 (2.05)

10: 5 + 5 (2.5)

上表没有列出如 2 + 3这种右操作数大于左操作数的情况,因为它等价于 3 + 2。

然后,我们在已经找到的解中寻找所有非最优组合,通过上表,将解转换为一个更优解。不断循环这个过程,我们就可以到达最优解。对于这个过程的证明也很简单,因为算法已经决定了我们无法再找到更优的解。

在应用这张表的时候,我们需要注意可转化性问题。比如(1,1,1,0,0) + (1,0,0,0,0) 无法转化成为(1,1,1,1,0) + (0,0,0,0,0),尽管表中显示 4 + 0 > 3 + 1。因此,我们构造获得的组合中,顺序也是重要的,尽管它并不影响算法的正确性。

posted on 2011-03-30 12:15  acmaru  阅读(169)  评论(1编辑  收藏  举报

导航