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

本文是《编程之美》一书的读书笔记,主要探讨了一种利用贪心策略解决实际问题的方法——如何在卖书中实现最大利润的折扣策略。通过对问题的深入分析和算法设计,展示了贪心算法在解决实际问题中的应用和有效性。
摘要由CSDN通过智能技术生成
《编程之美》读书笔记():卖书折扣问题的贪心解法
       每 次看完《编程之美》中的问题,想要亲自演算一下或深入思考的时候,都觉得时间过得很快,动辄一两个小时,如果再把代码敲一遍的话,需要的时间可能更长,真 是搞不懂通过微软面试的那些家伙的脑袋到底什么构造,书的序言中提到他们每次面试45分钟,还要写出程序?!在我看来,如果是控制CPU曲线或是中国象棋 问题或许还有可能,如果是买书折扣问题,我觉得真的是不太容易,尤其是如果当面试者钻进本题的贪心解法而不是动态规划算法的思路之后,因为我写这篇文章前 前后后大概用了5个小时 :-( 。不过我想只要是学习就不是浪费时间,今天上网看到微软的校园招聘网站又有更新,等我把这本书看完,就投简历过去试一试 :-) 。
1 问题描述及分析
       买书折扣问题的描述是,某出版社的《哈里波特》系列共有5卷,每本单卖都是8块钱,如果读者一次购买不同的k(k>=2)卷,就可以享受不同的折扣优惠,如下所示:

问题是如果给定一个订单,如何计算出最大的折扣数?
书中给出的动态规划解法这里就不再赘述了。不过,里面有两个问题需要单独关注一下:(1)如果订单描述为(X 1,X 2,X 3,X 4,X 5),其中X 1-X 5为所订数的数量,其所在位置为卷的编号,即第一卷X 1本,第二卷X 2本,…,第5卷X 5本;如果订单为:(X 3,X 2,X 4,X 5,X 1),则表示第一卷X 3本,第二卷X 2本,…,第五卷X 1本。我们可以很容易的看到,由于每本书的价格相同,所以折扣的多少仅仅在于如何选取而不在于究竟取那一卷书。因此,上面两个订单的最大折扣数是相同的,这也使得我们可以使用统一的方法(Y1,Y2,Y3,Y4,Y5),其中Y1≥Y1≥Y1≥Y1≥ Y5,来表示一个订单。作者将每本书的定价设为相同的是为了简化问题,因为如果每本书的定价也不同,则问题就会变得更加复杂,这时我们就不能仅仅考虑选几本书,还要考虑选哪几本。(2)书中说对于一次选择4至2本书的情况,(以3本书为例)只需考虑F(Y 1-1,Y 2-1,Y 3-1,Y 4,Y 5)的情况就可以了(注意,F为订单总价计算函数),并说“ 这样选择能够保证在选择当前折扣的情况下,剩下的书的种类最多, 它比其它组合都好”。 我觉得这个结论并不显然,下一步可选的书的种类多就能证明这个子问题比别的子问题更好?这点我不敢苟同,须知该问题的解决是一个多步选择的过程,所以要得 到这个结论就需要严格证明。如果这个条件不成立,那么书中给出的递归式也就不成立,即不能证明优化子结构性质成立。所以,对于如此重要的细节,书中应该给 出严格证明而不是一句话带过。
刚 开始拿到问题的时候就条件反射地想能不能用贪心算法,即每次都尽量按最大折扣来取书。书中给出一个反例:所给的订单是(2,2,2,1,1),按照贪心算 法,我们的选择方式是5+3,其折扣为5*0.25+3*0.10=1.55;而如果采用4+4的模式,则折扣数为2*4*0.20=1.6。这显然违背 了贪心规则。所以书中在解法二中采用了另外一种分析,作者计算了订单中书的数量在[1-10]区间内,各种不同的选取方法所能获得的最大折扣数:
本数
可能的分解本数
对应的折扣
对于2-5本,
直接按折扣
购买
2
3
4
5
5%
10%
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值