1. 1、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。。
  2. 2、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载
  3. 3、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
查看更多
exercise2 ACM

第二次作业(计1202蒋信厚) 贪心算法: 在对问题求解时,总是作出在当前看来是最好的选择。也就是说,不从整体上加以考虑,它所作出的仅仅是在某种意义上的局部最优解(是否是全局最优,需要证明)。贪心算法的基本步骤包括: 从问题的某个初始解出发。 2.采用循环语句,当可以向求解目标前进一步时,就根据局部最优策略,得到一个部分解,缩小问题的范围或规模。 将所有部分解综合起来,得到问题的最终解。 时间序列问题: 1、已知N个事件的发生时刻和结束时刻(见下表,表中事件已按结束时刻升序排序)。一些在时间上没有重叠的事件,可以构成一个事件序列,如事件{2,8,10}。事件序列包含的事件数目,称为该事件序列的长度。请编程找出一个最长的事件序列。 输入:第一行为事件的个数N,以下共输入N行,每一行都有两个整数构成,第一个整数为事件开始时间,第二个整数为事件结束时间,时间的编号为其所在的行数(从0开始计数)。 输出:输出一个最长的时间序列 输入示例: 12 1 3 3 4 0 7 3 8 2 9 5 10 6 12 4 14 10 15 8 18 15 19 15 20 输出示例: 0 1 5 8 10 解:用Begin[i]和End[i]表示事件i的开始时刻和结束时刻。则原题的要求就是找一个最长的序列a1a2…an,满足:Begin[a1]End[a1]=…= Begin[an]End[an];可以证明,如果在可能的事件a1a2…an中选取在时间上不重叠的最长序列,那么一定存在一个包含a1(结束最早)的最长序列(序列长度是指事件个数而不是时间长度!!!)。 示例中结束最早的事件是1 3,所以该事件就作为贪心算法中的初始解。因为目标是使时间序列中的事件尽可能多,所以每一步贪心算法都是将不重叠的结束最早的事件加入时间序列。 程序实现: //1.时间序列问题 #define Max 100 //事件个数上限 void main() { int Number;//事件个数Number int Begin[Max];//事件开始时刻//下标表示事件编号 int End[Max];//事件结束时刻 int result[Max];//存储最长的时间序列 int r=0;//存储result[]的下标 cinNumber; //判断事件个数是否超出上限 if(NumberMax) { cout事件个数超出上限!endl; exit(1); } //输入时间序列 for(int j=0;jNumber;j++) cinBegin[j]End[j]; //寻找最长的时间序列 //首先将第一个最早结束的事件加入最长时间序列 result[0]=0; //继续循环遍历所有事件构造最长时间序列 for(int i=1;iNumber;i++) { if(Begin[i]=End[result[r]]) result[++r]=i; } //输出最长时间序列编号 for(int k=0;k=r;k++) coutresult[k]\t; coutendl; } 区间覆盖问题: 用i来表示x轴上坐标为[i-1,i]的区间(长度为1),并给出M(1=M=200)个不同的整数,表示M个这样的区间。现在让你画几条线段覆盖住所有的区间,条件是:每条线段可以任意长,但是要求所画线段之和最小,并且线段的数目不超过N(1=N=50)。例如:M=5个整数1、3、4、8和11表示区间,要求所用线段不超过N=4条 1 2 3 4 5 6 7 8 9 10 11 输入:第一行为一个整数K,表示区间编号的最大数,当K=0时,程序结束,第二行为两个整数M和N,M表示需要覆盖的区间个数,N表示最大线段的数目,第三行包括M个正整数(不大于K),表示k个需要覆盖的区间编号。 输出:在给定条件下所画线段之和的最小值。 输入示例: 11 5 4 1 3 4 8 11 0 输出示例: 5 解: 方法一:(传统的一般解法) 先用一条最长的线段把整个区间覆盖起来,然后把区间点之间的空隔线段按照先长后短的顺序一一去掉,也就是贪心地使总线段长度尽可能短,知道线段的数量增加到到规定的数目停止; 方法二:(个人原创想到的思路) 其实思想与方法一一样,只不过这里逆向思考不是先用一条最长的线段把整个区间覆盖,二是用最短的线段把所有的区间点覆盖,也就是每个区间点用一条单位长度的线段覆盖,那么有n个区间点,就需要总长度为n的线段,然后把每个小线段一一连接起来,还是贪心地线连接距离最短的,尽量使总长度最短,直到线段数量减少到规

文档评论(0)

ddf55855 + 关注
实名认证
内容提供者

该用户很懒,什么也没介绍

1亿VIP精品文档

相关文档