贪心_HDOJ2037/NYOJ14最大区间调度问题
原题地址http://acm.hdu.edu.cn/showproblem.php?pid=2037
题目概述:
Input
输入数据包含多个测试实例,每个测试实例的第一行只有一个整数n(n<=100),表示你喜欢看的节目的总数,然后是n行数据,每行包括两个数据Ti_s,Ti_e (1<=i<=n),分别表示第i个节目的开始和结束时间,为了简化问题,每个时间都用一个正整数表示。n=0表示输入结束,不做处理。
Output
对于每个测试实例,输出能完整看到的电视节目的个数,每个测试实例的输出占一行。
Sample Input
12
1 3
3 4
0 7
3 8
15 19
15 20
10 15
8 18
6 12
5 10
4 14
2 9
0
Sample Output
5
题目分析:
经典时间序列问题,贪心算法,只考虑当前,不考虑全局,每次只考虑局部最优解,按右端点排序,依次处理。
/*给出节目开始和结束时间要求输出能看完的节目的数量*/ #include<bits/stdc++.h> using namespace std; struct TIME { int time_begin; int time_end; }; bool f(const TIME &a,const TIME &b) { return a.time_end < b.time_end;//按右端点排序 } int main(void) { int n; while(cin >> n && n) { vector<TIME> my_vec; while(n--) //输入和存储数据 { TIME t; cin >> t.time_begin >> t.time_end; my_vec.push_back(t); } sort(my_vec.begin(),my_vec.end(),f); vector<TIME>::iterator begin = my_vec.begin(),end = my_vec.end(); int sum = 1;//记录最多的空间数 TIME tmp = *begin; ++begin; //begin 从第二个开始,因为上去就先把第一个选了 sum也从1开始 while(begin != end) { //每次选取区间时候和前一个比较看是否覆盖 //.操作符比*操作符优先级高 得加小括号 if( (*begin).time_begin >= tmp.time_end ) { sum++; tmp = *begin; //更新tmp tmp表示最新被选上的区间 } ++begin;//往下走 } cout << sum << endl; } return 0; }
NYOJ14会场安排问题 链接http://acm.nyist.edu.cn/JudgeOnline/problem.php?pid=14
题目大意,知道活动开始和结束时间,要求出最多进行的活动
/*知道活动开始结束的时间,要求安排最多的活动,区间问题 * 如果上一个活动是t结束,下一个活动最早应该t+1开始*/ #include<bits/stdc++.h> using namespace std; struct S { int L; int R; }; bool f(const S &a,const S &b) { return a.R < b.R; } int main(void) { int N; cin >> N; while(N--) { int n; vector<S> v; cin >> n; while(n--) { S t; cin >> t.L >> t.R; v.push_back(t); } sort(v.begin(),v.end(),f);//按右端点排序 int count = 1,end = v[0].R; for(int i = 1; i < v.size();++i) { if(v[i].L > end) { end = v[i].R; ++count; } } cout << count << endl; } return 0; }
最大区间调度问题
数轴上有个区间,选出最多的区间,使得这些区间不互相重叠。
算法:
将所有区间按右端点坐标从小到大排序,顺序处理每个区间。如果它与当前已选的所有区间都没有重叠,则选择该区间,否则不选。

浙公网安备 33010602011771号