- 1、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。。
- 2、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载。
- 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)