总时间限制: 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
解析
此题可用贪心算法求解,思路为:将所有电影按结束时间先后排序,首先选择结束时间最早的电影,下一步电影为开始时间大于等于前一部电影的结束时间的电影中结束时间尽可能小的电影。
证明这种贪心算法的正确性:
假设贪心得到的序列为a1,a2,a3…
不使用贪心得到的最长电影序列为:b1,b2,b3…
现在证明对于任意的i,ai都可以替换bi:
设start[m]表示电影m的开始时间,end[m]表示结束时间,那么:
(1)end[a1]<=end[b1],所以a1可以替换b1;
(2)若找到一个i,end[ai]<=end[bi],又end[bi]<=start[bi+1],所以end[ai] <=start[bi+1],所以ai可以替换bi;此时ai+1是满足条件中,end最小的电影,因此用ai+1替换bi+1不会影响结果。
代码
#include<iostream>
#include<algorithm>
using namespace std;
struct mov{
int start;
int end;
}m[1000];
bool cmp(mov a,mov b){
return a.end<b.end;
}
int main(){
int n;
while(1){
cin>>n;
if(n==0) break;
else{
int sum=0;
for(int i=0;i<n;i++){
cin>>m[i].start>>m[i].end;
}
sort(m,m+n,cmp);
mov temp=m[0];
sum++;
for(int i=1;i<n;i++){
if(m[i].start>=temp.end){
sum++;
temp=m[i];
}
}
cout<<sum<<endl;
}
}
return 0;
}