- 1、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。。
- 2、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载。
- 3、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
- 4、该文档为VIP文档,如果想要下载,成为VIP会员后,下载免费。
- 5、成为VIP后,下载本文档将扣除1次下载权益。下载后,不支持退款、换文档。如有疑问请联系我们。
- 6、成为VIP后,您将拥有八大权益,权益包括:VIP文档下载权益、阅读免打扰、文档格式转换、高级专利检索、专属身份标志、高级客服、多端互通、版权登记。
- 7、VIP文档为合作方或网友上传,每下载1次, 网站将根据用户上传文档的质量评分、类型等,对文档贡献者给予高额补贴、流量扶持。如果你也想贡献VIP文档。上传文档
查看更多
* * * * * * * * * * * * * * * * * * * * 贪心与分治 贪心方法 按照当前的状态,选择最好的决策,这就是贪心法。在实际的应用中,人们往往不可能精确计算出怎样才是最好的决策,只能凭借往常的经验,保证每一步都是最好的选择。在解题的过程中,这样的算法一般是比较容易想到并且易于编程实现的。能够使用贪心算法解决的问题,必然是每次都进行最优的选择,并且通过证明其得到的最后结果也是最优的。 反之,如果不能证明每次进行最优选择后,最终会得到最优的结果,就不能使用贪心算法。其实,大部分的问题都是不能使用贪心算法的, 简单的例子:现有10元、7元、2元、1元四种纸币,使用的张数不限,需要用这四种纸币凑成p元钱,怎样用最少的张数达到此要求。 此题我们很容易就想到了贪心的算法,即每次尽量选面值大的纸币。但是,在p=14时,贪心算法的结果为14=10+2+2,而最优结果为14=7+7,贪心显然是不对的。然而,如果我们将其中的7元纸币换成5元纸币,贪心算法却又是对的。这就需要我们用证明来判断了。 例题1 罚款问题 现有一台机器以及n项要完成的工作,该机器每完成一项工作需要1的单位时间,而工作i如果没有在t[i]的时间内完成,将会受到c[i]的罚款。求怎样安排工作的顺序,使完成工作后总的罚款数最少。 分析 要使罚款最少,我们显然应尽量完成c[i]值较大的工作。 此时,我们可以将工作按c[i]从大到小进行排序,然后按照排好的顺序依次对工作进行安排,安排的规则为:使处理工作i的时间既在t[i]之内,又尽量靠后;如果t[i]之内的时间都已经排满,就放弃处理此项工作。 ? 证明 假设按照上述方法得到的解不是最优的,那么必然存在某个工作j应当安排到处理的过程中,却没有得到安排。假设我们要将该工作安排进去,由于时间t[j]内都已经排满,就必然需要将一个已安排的工作k与之替换,而c[k]=c[j],这样替换显然会增加罚款的数额。因此,除上述安排方法以外的安排方法都不会使罚款的数额减少,可得上述方法得到的结果是最优的。 例题2: INT(整数区间) 定义 一个整数区间[A,B],A﹤B,是一个从A开始,至B结束的连续整数的集合。 任务是从文件中读取区间的个数及其对它们的描述,找出满足下述条件的所含元素个数最少的集合中元素的个数:对于每一个区间,都至少有两个不同的整数属于该集合。 输入: 文本文件INT.IN的首行包括区间的数目N,1≦N≦10000。接下来的N行,每行包括两个整数A,B,被一空格隔开,0≦A≦B≦10000,它们是某一个区间的开始值和结束值。 输出:最少元素数目。 示例输入: 4 3 6 2 4 0 2 4 7 输出: 4 分析 本题 “会场安排”问题十分相似,可以用同样的贪心方法:按照所有区间的结束位置排序,结束位置相同的项,开始位置小的项在前。从区间1到区间n进行循环,对于当前区间,若集合中的数不能覆盖它,则从区间末尾向前扫描,若当前数未在集合中出现,则将该数加入集合,直至使集合能覆盖该区间为止。 示例: 【0,1,2】 【2,3,4】 【3,4,5,6】【4,5,6,7】 【】 【2】 【2 ,1】 【2,1,4】 【2,1,4,6】 上述算法的指导思想是在某一区间中排列越靠后的数对以后区间的影响越大,即它在以后区间出现的可能性越大,但未经严格数学证明 ? 具体实现 由于pascal规定的集合类型只有[0..255],因此在实现时不能使用集合作数据结构,用数组直接保存也不行,因为在数组中查找数据相当费时,注意到每个区间中的数大小不超过10000,可用一个下标为[0..10000]的布尔型数组标记该数是否出现过,从而解决这一问题。 例题3:零件分组 某工厂生产一批棍状零件,每个零件都有一定的长度(Li)和重量(Wi)。现在为了加工需要,要将它们分成若干组,使每一组的零件都能排成一个长度和重量都不下降(若ij,则Li=Lj,Wi=Wj)的序列。请问至少要分成几组? 输入:第一行为一个整数N(N=1000),表示零件的个数。第二行有N对正整数,每对正整数表示这些零件的长度和重量,长度和重量均不超过10000。 输出:仅一行,即最少分成的组数。 样例(STICK.IN) 5 8 4 3 8 2 3 9 7 3 5 STICK.OUT 2 例题4:乘船问题(HNCOI) 有N个人需要乘船,而每船最多只能载两人,且必须同名或同姓。求最少需要多少条船。 问题分析 看到这道题,很多人都会想到图的数据结构:将N个人看作无向图的N个点,凡同名或同姓的人之间都连上边。 要满足用船最少的条件,就是需要尽量多的两人共乘一条船,表现在图中就是要用最少的边
文档评论(0)