【题面】
4151:电影节
总时间限制:1000ms 内存限制:65536kB
描述
大学生电影节在北大举办! 这天,在北大各地放了多部电影,给定每部电影的放映时间区间,区间重叠的电影不可能同时看(端点可以重合),问李雷最多可以看多少部电影。
输入
多组数据。每组数据开头是n(n<=100),表示共n场电影。
接下来n行,每行两个整数(0到1000之间),表示一场电影的放映区间。n=0则数据结束。
输出
对每组数据输出最多能看几部电影
样例输入
8
3 4
0 7
3 8
15 19
15 20
10 15
8 18
6 12
0
样例输出
3
【思路】
贪心,按照时间顺序从前向后选取去看什么电影。如果两个电影a和b,a的终止时间早于b的终止时间,那么选a之后还能看的电影一定不劣于选b之后还能看的电影。
而又因为我们是从前向后按照时间顺序去决定电影的选取的,所以我们不需要考虑之前的电影的选取情况。即只要在当前的状态下,存在两个电影,它们都可以被选取为下一个被看的电影,那么我们就选结束时间早的那个。
那我们不妨去看每一个时刻结束时间最早的那个电影,如果这个电影可以看,那么就去看。我们可以证明这种看电影的策略不劣于任何其他的策略。
这样的话,直接把所有的电影按照右端点从小到大排序,再一个一个验证当前这个电影的时间是否与之前选取的电影时间相冲突就可以了。具体做法,可以记录一下当前看的最后一个电影的结束时间,把它和下一个电影的开始时间相比较。
【代码】
#include<cstdio>
#include<algorithm>
using namespace std;
#define maxn (100 + 10)
struct film{
int L, R;
}ns[maxn];
bool cmp(film a, film b){
return a.R < b.R;
}
int main(){
int n;
while(scanf("%d", &n) && n){
for(int i=1; i<=n; i++)
scanf("%d%d", &ns[i].L, &ns[i].R);
sort(ns + 1, ns + n + 1, cmp);
int tnow = 0, cnt = 0;
for(int i=1; i<=n; i++){
if( tnow<=ns[i].L ){
cnt ++;
tnow = ns[i].R;
}
}
printf("%d\n", cnt);
}
return 0;
}
2018.1.23 GGN