- 1、本文档共21页,可阅读全部内容。
- 2、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。
- 3、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载。
- 4、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
查看更多
ACM中期培训 讲解人:李川皓 制作人:曾卓敏 哈尔滨理工大学ACM集训队 贪心和分治 贪心: 贪心,顾名思义贪心算法总是作出在当前看来最好的选择。也就是说贪心算法并不从整体最优考虑,它所作出的选择只是在某种意义上的局部最优选择。当然,贪心算法得到的最终结果也是整体最优的。 贪心只是一种思想,我们举几个例子来说明一下~ 事件序列问题 已知N个事件的发生时刻和结束时刻(见下表,表中事件已按结束时刻升序排序)。一些在时间上没有重叠的事件,可以构成一个事件序列,如事件{2,8,10}。事件序列包含的事件数目,称为该事件序列的长度。请编程找出一个最长的事件序列。 策略:尽可能选择结束时间早的-先排序 分析:由于输入的活动以其完成时间的非减序排列,所以算法每次总是选择具有最早完成时间的相容活动加入集合A中。直观上,按这种方法选择相容活动为未安排活动留下尽可能多的时间。也就是说,该算法的贪心选择的意义是使剩余的可安排时间段极大化,以便安排尽可能多的相容活动。 算法的效率:用O(nlogn)的时间排序。然后用O(n)的时间来安排n个活动 事件序列问题 一般贪心的题目都要进行对某一属性的排序工作 例题1:n个人排队接水,编号为1到n,每个人的接水时间为Ti,请编程找出这n个人的排队序列(接水时间一样的按照他们的编号排队),使得他们的平均等待接水时间最小。 1 = n = 100000。 0 = Ti = 200000。 Simple Input: //有10个人接水 56 12 1 99 1000 234 33 55 99 812 //每个人接水花费时间 Simple Output:291.90 //平均每个人接水花费时间,精确到小数点后2位 分析: 想一想,如果接水时间长的放在前面,那么后面的人等待时间就会增长,所以总的接水时间就会变得更长。 所以就应该按接水时间从短到长排序,然后累计每个人花费的时间,再除以总人数就是平均花费时间了。 例题2: Doing homework again Problem Description 小朋友现在需要完成N门科目的作业。现假设他完成一门作业所需时间为1天。给出N门作业的上交截止时间(天),以及不及时交作业期末成绩所被扣的分数。假如小朋友现在没办法将这些作业全部都完成,那他该如何安排使得他所扣的总分数最少呢? 例: 假如N=7,即现在有7门作业要完成,各科的属性见下表: 答案:5,即不写第一个和第二个作业 分析:在希望被扣的分数尽可能少的情况下,自然要先完成那些扣分多的作业,同时还要兼顾考虑作业的截止日期,然后作出决策。 方法一:对截止日期进行递増排序,若截止日期相同,则按作业不完成所扣分数递减排序。于是对上边的用例有: 前4个肯定可以在给定的期限内按时完成。从第5个开始,需要做一些工作:将第5个所扣分数与前边的4个最小值比较,若比最小值大,则将这第5项替换前边最小值项。此处即将(4,5)替换掉(1,3) 这样这位小朋友就应该写(4,5)这项作业而不写(1,3)才能保证在当前所扣的分数最少。 接下来取(4,2)与前4个中的扣分最小值比较,发现都比它大,那就不替换,直接不写这个作业。至此已经定下来写4科,而不写2科即(1,3)和(4,2)。最后(6,1)可以直接在第五天来写。最后扣分最少为5分。 由于要与之前的最小值作比较,程序中可以使用优先队列,或用小根堆维护当前确定下来的前k天写的作业。数据量不算大时,也可以用插入排序方式维护这个单调队列 这种方法使用了贪心的思想,但算法执行过程中需要维护一个单调队列,稍微麻烦些。 方法二:按作业所扣分数递减排序。于是乎: 然后假设有一个维护着天数的格子,将(4,7)放到第4天那格子中,(2,6)放在第2天那格子中,又遇到(4,5),由于第4天格子已被占用,则将(4,5)放到第4天之前空闲的格子中,此处放在1或3都可以,然后(3,4)也会把前边4个格子占上。来了(1,3)发现前边没他地方了,那就不写这门。因为按照贪心思想按扣分由大到小排序后,前边上占位的肯定比它扣分多,所以只能不写这个分数少的了。 分治: 分治(divide-and-conquer)就是“分而治之”的意思,其实质就是将原问题分成n个规模较小而结构与原问题相似的子问题;然后递归地解这些子问题,最后合并其结果就得到原问题的解。当n=2时的分治法又称二分法。 其三个步骤如下; 分解(Divide):将原问题分成一系列子问题。 解决(Conquer):递归地解各子问题。若子问题足够小,则可直接求解。 合并(combine);将子问题的结果合并成原问题的解。 分治思想 问题S S的解 问题S1 …… 问题S2 问题Si 问题Sn …… S1的解 …… S2
文档评论(0)