题目描述
题目描述:
“今年暑假不AC? ”
“是的。”
“那你干什么呢? ”
“看世界杯呀,笨蛋!”
确实如此,世界杯来了,球迷的节日也来了,估计很多ACMer也会抛开计算机,奔向电视了。 作为球迷,一定想看尽量多的完整的比赛。当然,作为新时代的好青年,你一定还会看一些其 他的节目,如《新闻联播》(永远不要忘记关心国家大事)《非常6+7》《超级女声》及王小丫主 持的《开心辞典》等,假设你已经知道了所有你喜欢看的电视节目的转播时间表,你会合理安 排吗?(目标是能看尽量多的完整节目。)
输入:
输入数据包含多个测试实例,每个测试实例的第一行只有一个整数n (»<100),表示你喜欢看 的节目的总数;然后是〃行数据,每行包括两个数据Is和Tie (1 </<«),分别表示第z•个 节目的开始和结束时间,为简化问题,每个时间都用一个正整数表示。〃 =0表示输入结束,不做 处理。
输出:
对于每个测试实例,输出能完整看到的电视节目的个数,每个测试实例的输出占一•行。
样例输入:
12
1 3
34
0 7
38
15 19
15 20
10 15
8 18
6 12
5 10
414
2 9
0
样例输出:
5
算法
贪心思想
贪心问题
局部最优—>全局最优
每次选择结束时间最早的节目,即剩余的时间最多
首先思考这样一个问题:第一个节目应该选什么?
①选择开始时间最早的:如果有电视节目A[0,5],B[1,2],C[3,4],那么显然选择最 先开始的节目并不一定能够得到最优解。
②选择持续时间最短的:如果有电视节目A[0,10],B[11,20],C[9,12],那么显然选 择持续时间最短的节目也并不一定能够得到最优解。
③选择结束时间最早的:在以上两组案例中优先选择结束时间最早的节目,是可以 得到最优解的。那么它是否就真的是我们所需要的贪心策略呢?
在最优解中,观看的第一个的节目一定是所有节目中结束时间最早的那个节目。因为 这样才能保证看完第一个节目后,剩余观看时间的最大化。那么在看完第一个节目后,如 法炮制,在剩余观看时间内选择结束时间最早且仍能观看的那个节目。以此类推,直到剩 余观看时间内没有任何节目可以看为止。通过不断地利用这种贪心策略,就能完成最优解 的求解。
因此,具体的做法可以是首先对所有节目按照结束时间的早晚进行升序排序,然后按 照这一顺序逐一对节目进行判断:
①如果当前时间能够观看该节冃(即当前时间小于等于该节目的开始时间),那么就 选择观看该节目,并将当前时间更新为该节目的结束时间。
②如果当前时间不能够观看该节目(当前时间已超过该节目的开始时间),那么就选 择放弃观看该节目,进而去判断下–个节目是否符合要求。
C++ 代码
#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<queue>
#include<stack>
#include<vector>
using namespace std;
/*贪心问题
局部最优—>全局最优
每次选择结束时间最早的节目,即剩余的时间最多
*/
struct time{
int starttime;
int endtime;
};
const int maxn=110;
time t[maxn];
bool cmp(time t1,time t2){
return t1.endtime<t2.endtime;
}
int main(){
int n;
while(cin>>n){
if(n==0){
break;
}
for(int i=0;i<n;i++){
cin>>t[i].starttime>>t[i].endtime;
}
sort(t,t+n,cmp);
int current=0;
int ans=0;
for(int i=0;i<n;i++){
if(current<=t[i].starttime){
current=t[i].endtime;
ans++;
}
}
cout<<ans<<endl;
}
return 0;
}