P2255 [USACO14JAN]记录奥林比克
题目描述
农民约翰热衷于所有寒冷天气的运动(尤其是涉及到牛的运动), 农民约翰想录下尽可能多的电视节目。 为moolympics电视时间表由N个不同的节目 (1 < = n=150),每个具有指定的开始时间和结束时间。FJ 有一个双调谐器录音机,可以同时录制两个节目。 请帮助他确定他能录制的节目的最大数量。
输入输出格式
输入格式:
第1行:整数n。 第2行.. 1 + n:每行包含单个的开始和结束时间 程序(范围为0…1000000000的整数)。
输出格式:
仅一行,节目FJ可以记录的最大数量。
输入输出样例
一道很有意思的贪心题。
我们先把数据按a[i]排序,然后开两个变量m1、m2存b[i]的最小值和次小值,有以下三种情况:
- 读入一个a[i]>=m1,则 ans++;m1=min(m2,b[i]);m2=max(m2,b[i]);
- 读入一个a[i]<m1且b[i]<m1,则 m2=m1;m1=b[i];
- 读入一个a[i]<m1且m1<b[i]<m2,则 m2=b[i];
代码如下:
1 #include<iostream> 2 #include<string> 3 #include<cmath> 4 #include<cstring> 5 #include<cstdio> 6 #include<stack> 7 #include<queue> 8 #include<algorithm> 9 #define maxn 1005 10 using namespace std; 11 12 inline int read() 13 { 14 char c=getchar(); 15 int x=1,res=0; 16 while(c<'0'||c>'9') 17 { 18 if(c=='-') 19 x=-1; 20 c=getchar(); 21 } 22 while(c>='0'&&c<='9') 23 { 24 res=res*10+(c-'0'); 25 c=getchar(); 26 } 27 return x*res; 28 } 29 30 struct node 31 { 32 int a,b; 33 }g[maxn]; 34 int n,aa,bb,ans; 35 int m1,m2; 36 37 bool cmp(node a,node b) 38 { 39 return a.a<b.a; 40 } 41 42 int main() 43 { 44 n=read(); 45 for(int i=1;i<=n;i++) 46 { 47 aa=read();bb=read(); 48 g[i].a=aa;g[i].b=bb; 49 } 50 sort(g+1,g+1+n,cmp); 51 m1=min(g[1].b,g[2].b); 52 m2=max(g[1].b,g[2].b); 53 for(int i=3;i<=n;i++) 54 { 55 if(g[i].a>=m1) 56 { 57 ans++; 58 m1=min(m2,g[i].b); 59 m2=max(m2,g[i].b); 60 } 61 else 62 { 63 if(g[i].b<m1) 64 { 65 m2=m1; 66 m1=g[i].b; 67 } 68 else if(g[i].b<m2) 69 { 70 m2=g[i].b; 71 } 72 } 73 } 74 cout<<ans+2; 75 return 0; 76 }
为什么说这题很有意思呢?那是因为这题就是在只有一个录音机的基础上又加上了一个,另外我这里还有一个大胆的想法,如果把录音机的数目改成3个、4个甚至说m个,又该怎么做呢?有人可能会说不就是多开几个变量吗?但是如果分析一下,就会发现随着录音机数目的增多,所有可能出现的情况也会随之增多,如果把这些情况一一列举出来显然不现实,然而我自己也不会做呀,那就先把问题放在这里好了,说不定以后还可以出一道毒瘤题。