买书问题

编程之美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。因此,我们构造获得的组合中,顺序也是重要的,尽管它并不影响算法的正确性。

转载于:https://www.cnblogs.com/acmaru/archive/2011/03/30/1999687.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值