- 1、本文档共34页,可阅读全部内容。
- 2、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。
- 3、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载。
- 4、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
查看更多
第六章 贪心算法 【例7】活动选择 学校在最近几天有n个活动,这些活动都需要使用学校的大礼堂,在同一时间,礼堂只能被一个活动使。由于有些活动时间上有冲突,学校办公室人员只好让一些活动放弃使用礼堂而使用其他教室。 现在给出n个活动使用礼堂的起始时间begini和结束时间endi(begini endi),请你帮助办公室人员安排一些活动来使用礼堂,要求安排的活动尽量多。 【输入】 第一行一个整数n(n=1000); 接下来的n行,每行两个整数,第一个begini,第二个是endi(begini endi =32767) 【输出】 输出最多能安排的活动个数。 【样例输入】 11 3 5 1 4 12 14 8 12 0 6 8 11 6 10 5 7 3 8 5 9 2 13 【样例输出】 4 【算法分析】 ? 算法模型:给n个开区间(begini,endi), 选择尽量多的区间, 使得两两不交。 ? 做法: 首先按照end1=end2…=endn的顺序排序,依次考虑各个活动, 如果没有和已经选择的活动冲突, 就选; 否则就不选。 ? 正确性: 如果不选end1, 假设第一个选择的是endi,则如果endi和end1不交叉则多选一个end1更划算; 如果交叉则把endi换成end1不影响后续选择。 【参考程序】 #includeiostream using namespace std; int n,begin[1001],end[1001]; void init() { cinn; for(int i=1;i=n;i++) cinbegin[i]end[i]; } void qsort(int x,int y) { int i,j,mid,t; i=x;j=y;mid=end[(x+y)/2]; while(i=j) { while(end[i]mid) ++i; while(end[j]mid) --j; if(i=j) { t=end[j];end[j]=end[i];end[i]=t; t=begin[j];begin[j]=begin[i];begin[i]=t; ++i;j; } } if(xj) qsort(x,j); if(iy) qsort(i,y); } void solve() { int ans=0; for(int i=1,t=-1;i=n;++i) //在初始化循环变量的同时,初始化t。 //令t=-1可以使第一个区间与其他区间的操作相同。 if(begin[i]=t) {++ans;t=end[i];}//如果当前活动与之前最后结束的活动不冲突, 就接受当前活动。 coutansendl; } int main() { init(); qsort(1,n); solve(); return 0; } 【例8】整数区间 请编程完成以下任务: 1.从文件中读取闭区间的个数及它们的描述; 2.找到一个含元素个数最少的集合,使得对于每一个区间,都至少有一个整数属于该集合,输出该集合的元素个数。 【输入】 首行包括区间的数目n,1=n=10000,接下来的n行,每行包括两个整数a,b,被一空格隔开,0=a=b=10000,它们是某一个区间的开始值和结束值。 【输出】 第一行集合元素的个数,对于每一个区间都至少有一个整数属于该区间,且集合所包含元素数目最少。 【样例输入】 4 3 6 2 4 0 2 4 7 【样例输出】 2 【算法分析】 ?算法模型:给n个闭区间[ai,bi], 在数轴上选尽量少的点,使每个区间内至少有一个点。 ?算法:首先按b1=b2=...=bn排序。每次标记当前区间的右端点x,并右移当前区间指针,直到当前区间不包含x,再重复上述操作。 ?如下图,如果选灰色点,移动到黑色点更优。 【参考程序】 #incl
文档评论(0)