1 问题描述及分析
买书折扣问题的描述是,某出版社的《哈里波特》系列共有5卷,每本单卖都是8块钱,如果读者一次购买不同的k(k>=2)卷,就可以享受不同的折扣优惠,如下所示:

问题是如果给定一个订单,如何计算出最大的折扣数?
书中给出的动态规划解法这里就不再赘述了。不过,里面有两个问题需要单独关注一下:
(1)如果订单描述为X:(X1,X2,X3,X4,X5),其中X1,X2,X3,X4,X5为所订书的数量,其所在位置为卷的编号,即第一卷X1本,第二卷X2本,…,第5卷X5本,由于每本书的价格相同,所以折扣的多少仅仅在于如何选取而不在于究竟取那一卷书。我们将(X1,X2,X3,X4,X5)按照大小顺序重新排列成为一个新的序列Y:(Y1,Y2,Y3,Y4,Y5),其中Y1≥Y2≥Y3≥Y4≥Y5。为什么要这样排列呢?因为我们的关注点不在于第一卷书要买几本,而在于,如何将这些书组合起来,使得组合后的优惠更多。
   (2)下一步可选的书的种类多就能证明这个子问题比别的子问题更好?这点我不敢苟同,须知该问题的解决是一个多步选择的过程,所以要得到这个结论就需要严格证明。如果这个条件不成立,那么书中给出的递归式也就不成立,即不能证明优化子结构性质成立。
作者计算了订单中书的数量在[1-10]区间内,各种不同的选取方法所能获得的最大折扣数:
本数
可能的分解本数
对应的折扣
对于2-5本,
直接按折扣
购买
2
3
4
5
0.1
0.3
0.8
1.25
6
=5+1
=4+2
=3+3
=2+2+2
1.25
0.9
0.6
0.3
7
=5+2
=4+3
1.35
1.1
8
=5+3
=4+4
=3+3+2
=2+2+2+2
5*25%+3*10%=1.55
4*20%+4*20%=1.6
0.7
0.4
9
=5+4
=5+2+2
=4+3+2
=3+3+3
2.05
1.45
1.2
0.9
10
=5+5
=4+4+2
=4+3+3
=2+2+2+2+2
2.5
1.7
1.4
0.5
表1-2 折扣计算表
    但是,这里出现了一个违反贪心规则的地方,当我们要买8本书的时候,我们的选择方式是5+3,其折扣 为5*0.25+3*0.10=1.55;而如果采用4+4的模式,则折扣数为2*4*0.20=1.6。
作者采用了改进的贪心算法,将所有5+3的组合全部替换成4+4的组合。
(由于书中的表述方式不清晰,甚至是错误,我将采用我自己的表达方法,例如:一组“4种不同卷”的组合,就表示这一组书由4本不同卷的书组成,<卷一,卷二,卷四,卷五>或者<卷一,卷二,卷三,卷五>)

按照书中的例子,X=(2,2,1,1,3), 我们将其转换成Y的形式,则Y=(3,2,2,1,1)。
按照贪心策略,我们可以取出一组“5种不同卷”的组合,即Y5=1组,这时,Y=(2,1,1,0,0);
接下来,我们要取出“4种不同卷”的组合,发现条件不成立,不能取出一组不同的四卷书来,即Y4-Y5=1-1=0组;
但是,我们可以取出1组“3种不同卷”的组合,即Y3-Y4=2-1=1组,这时,Y=(1,0,0,0,0);
接下来,我们要取出“2种不同卷”的组合,发现条件不成立,不能取出一组不同的两卷书来,即Y2-Y3=2-2=0组;
最后,我们还可以取出1组“1种不同卷”的组合,即Y1-Y2=3-2=1组。
这样,我们对订单中的9本书做出了如上的分组。
但是根据表1-2的反例,我们要做出一些调整,将所有的5+3组合换成4+4组合。“5种不同卷”有1组(Y5=1),“3种不同卷”有1组(Y3-Y4=2-1=1),因此K=min{Y5,Y3-Y4}=1。
这时,我们对订单中的9本书所做出的分组就变成了:
5种不同卷 Y5-K=1-1=0
4种不同卷 Y4-Y5+2K=1-1+2=2
3种不同卷 Y3-Y4-K=2-1-1=0
2种不同卷 Y2-Y3=2-2=0
1种不同卷 Y1-Y2=3-2=1

  上述方法对于10本之内的情况适用。但是对于十本以上的情况呢?

作者想把多余10本的订单分成 若干个小于10的订单组,并把每组的最大折扣相加,以得到全局最优解,关于这一点我将在下面进行说明。
2 贪心算法是否适用的分析
贪心算法的适用有两个必要条 件,即优化子结构和贪心选择性。第一个性质由于已经证明可以适用动态规划算法,所以优化子结构性质显然成立(假如书中的动态规划递归式成立的话)。现需要 证明其贪心选择性,即如何“贪心”的进行选择。显然每次都查找最大的折扣数进行处理的贪心方法是行不通的,那么是贪心方法真的不行还是我们“贪”的不正确 呢?我们下面就来分析。
贪心选择性的含义是,一个全 局最优解可以通过局部最优选择来达到,换句话说,当考虑作何选择时,我们只考虑对当前问题最佳的选择而不考虑子问题的结果。贪心算法所做的当前选择可能要 依赖于已经做出的所有选择,但不依赖于有待于做出的选择或子问题的解。所以,贪心策略通常是自顶向下地,一个一个地做出贪心选择,不断地将给定的问题归约 为更小的问题。当然,在此之前我们必须证明在每一步所做的贪心选择最终能产生一个全局最优解,这也正是本题的关键所在。
书中解法二给出的分组的思想是可以借鉴的,但是显然犯了方向性的错误。因为贪心算法的关键在于“选择”, 即从当前的状态来“贪心地”从多种子状态中选择一个“当前的”最优解进行下去,并由其贪心选择性而使最终的解刚好是最优解。既然书中最后采用的还是(经修 改后的)贪心算法,就不应该把整体的问题分成若干组来执行。这是因为贪心算法的上一次选择与下一次选择之间是带有连续性的,并不能够将它们拆开处理;而如 果要拆开处理之后再将结果相加,就还需要证明拆分是使得结果最优的拆分。所以我们的目标最终还是应该定为寻找如何“贪”!其实作者的意图是对的,但实际目 标应该定为限制本次选择对于此后选择的影响,或使本次选择的影响仅限于下一次选择,这也是表格1-1只需要计算到10的原因(两次选择最多选择10本书),但由于下一次选择的影响可能会影响下下次的选择,所以我们不能硬性将这些选择拆开然后再相加,而只能一次一次地完成选择。
部分内容分析来自:
http://www.kuqin.com/algorithm/20080417/6890.html

转载于:https://www.cnblogs.com/z-j-n-2015/p/5072417.html

编程之美——买书问题:贪心算法相关推荐

  1. 《编程之美》1.4 买书问题 贪心法则

    在书中,作者分析两种解法 解法一是贪心,最后得到的结论是:贪心不成立 解法二是dp , 也类似于递归,最后是成立的 在这里我们重点分析贪心法不成立的原因,以及如何改进 贪心法的适用有两个必要条件,即优 ...

  2. [编程之美]买票找零(卡特兰数)

    第一次看这题的时候没有好好注意,后来发现这是一类大问题,学习了卡特兰数这个概念,顺便又复习了高中的排列组合知识... 一.书中问题 先看一下书中引入卡特兰数的例子: <编程之美>4.3买票 ...

  3. js算法:动态规划-金矿模型与买书问题(附js源码)

    本文内容介绍转自博客:通过金矿模型介绍动态规划,后面附上我自己实现的js代码: 经典的01背包问题是这样的: 有一个包和n个物品,包的容量为m,每个物品都有各自的体积和价值,问当从这n个物品中选择多个 ...

  4. 面试难,应聘难,好工作,今安在?——《编程之美——微软技术面试心得》为你探路!即将上市,敬请关注!

    这本书是我目前所见到的优秀面试试题的最全集,包含大量有趣且有启发性的题目,一方面对于学生的指导意义重大,另一方面,即使对于我们这些已经工作的人来说,也不失为一本充满智慧与趣味的好书."    ...

  5. 《编程之美》 查找最大(小)的k个元素

    http://blog.csdn.net/v_july_v/article/details/6370650 http://blog.csdn.net/insistgogo/article/detail ...

  6. 编程之美 - 读书笔记 - 卖书折扣问题的贪心解法

    <编程之美>读书笔记(四):卖书折扣问题的贪心解法 每 次看完<编程之美>中的问题,想要亲自演算一下或深入思考的时候,都觉得时间过得很快,动辄一两个小时,如果再把代码敲一遍的话 ...

  7. 《编程之美》读书笔记(四): 卖书折扣问题的贪心解法

    <编程之美>读书笔记(四):卖书折扣问题的贪心解法 每次看完<编程之美>中的问题,想要亲自演算一下或深入思考的时候,都觉得时间过得很快,动辄一两个小时,如果再把代码敲一遍的话, ...

  8. 买书动态规划java_《编程之美》买书问题——动态规划

    问题描述: 在节假日的时候,书店一般都会做促销活动.由于<哈利波特>系列相当畅销,店长决定通过促销活动来回馈读者.上柜的<哈利波特>平装本系列中,一共有五卷.假设每一卷单独销售 ...

  9. 从《编程之美》买票找零问题说起,娓娓道来卡特兰数——兼爬坑指南

    转自:从<编程之美>买票找零问题说起,娓娓道来卡特兰数--兼爬坑指南 引子: 大约两个月前,我在练习一些招聘的笔试题中,有一道和卡特兰数相关.那时还没来得及开始仔细看<编程之美> ...

最新文章

  1. django html数据库连接,Django数据库连接的问题
  2. php中使用like查询,php like 查询
  3. 【TODO】HTML label
  4. 【SKILLS】About the phonetics
  5. Shell(6): 多线程操作及线程数
  6. 到底谁应该对软件开发的质量负责?
  7. 如何启动一个Vue3.x项目
  8. 超高频RFID智慧酒店管理系统解决方案
  9. 4参数逻辑曲线公式及其含义
  10. 如何助力鸿蒙发展,实话实说:华为以一已之力,能不能推动鸿蒙系统的发展 - 区块网...
  11. SSD_Resnet 飞机与油桶数据集实战
  12. Edge、Chrome自定义新标签页网址
  13. 香港中文大学-人脸识别进展-2014-06
  14. 干货 | Between 运算符
  15. Kryo的基本简单使用
  16. 新东方东方优播iOS面试经历
  17. JAVA开发明源云面经(已OC)
  18. 筛多肽(水解,活性预测,毒性预测,过敏性预测....)
  19. 打分法收益模型 回归法风险模型 最简明分析实测
  20. 解决 Edge 浏览器 阻止下载

热门文章

  1. html显示任务进度,(原创)asp.net利用多线程执行长时间的任务,客户端显示出任务的执行进度的示例(二)...
  2. java模拟器apk闪退_急,求帮助,eclipse生成apk安装以后闪退
  3. 本地两台虚拟机构建NFS服务器和客户端
  4. 在ubuntn kylin系统eclipse中Java语言helloworld程序
  5. 【大数据】朴素的数据价值观
  6. 软件项目管理0706:工匠精神
  7. Android中在使用Room时提示:Cannot figure out how to save this field into database. You can consider adding a
  8. Node响应中文时解决乱码问题
  9. Mysql 提示:Communication link failure
  10. SSM整合+分页+Druid+CRU+log4J+junit+事务+Json+Bootstrap入门教程总览目录