CodeForces - 589F —(二分+贪心)
A gourmet came into the banquet hall, where the cooks suggested n dishes for guests. The gourmet knows the schedule: when each of the dishes will be served.
For i-th of the dishes he knows two integer moments in time ai and bi (in seconds from the beginning of the banquet) — when the cooks will bring the i-th dish into the hall and when they will carry it out (ai < bi). For example, if ai = 10 and bi = 11, then the i-th dish is available for eating during one second.
The dishes come in very large quantities, so it is guaranteed that as long as the dish is available for eating (i. e. while it is in the hall) it cannot run out.
The gourmet wants to try each of the n dishes and not to offend any of the cooks. Because of that the gourmet wants to eat each of the dishes for the same amount of time. During eating the gourmet can instantly switch between the dishes. Switching between dishes is allowed for him only at integer moments in time. The gourmet can eat no more than one dish simultaneously. It is allowed to return to a dish after eating any other dishes.
The gourmet wants to eat as long as possible on the banquet without violating any conditions described above. Can you help him and find out the maximum total time he can eat the dishes on the banquet?
Input
The first line of input contains an integer n (1 ≤ n ≤ 100) — the number of dishes on the banquet.
The following n lines contain information about availability of the dishes. The i-th line contains two integers ai and bi (0 ≤ ai < bi ≤ 10000) — the moments in time when the i-th dish becomes available for eating and when the i-th dish is taken away from the hall.
Output
Output should contain the only integer — the maximum total time the gourmet can eat the dishes on the banquet.
The gourmet can instantly switch between the dishes but only at integer moments in time. It is allowed to return to a dish after eating any other dishes. Also in every moment in time he can eat no more than one dish.
Examples
3
2 4
1 5
6 9
6
3
1 2
1 2
1 2
0
Note
In the first example the gourmet eats the second dish for one second (from the moment in time 1 to the moment in time 2), then he eats the first dish for two seconds (from 2 to 4), then he returns to the second dish for one second (from 4 to 5). After that he eats the third dish for two seconds (from 6 to 8).
In the second example the gourmet cannot eat each dish for at least one second because there are three dishes but they are available for only one second (from 1 to 2).
题意:给出了n个时间段,你需要在每个时间段中挑选相同长度的一段(不需要连续),问你挑选的最长时间段的总和是多少。比如第一个样例,第一段挑选2-4两秒,第二段挑选1-2,4-5两秒,第三段挑选6-8两秒,一共6秒,而第二个样例连一秒都分不出,所以0。
思路:用二分枚举0到题目限制的最大值,判断每次二分的中点是否可以,找出满足条件的最大值。
判断是否可以的方法是对每个时间段的终点进行从小到大排序,然后标记它需要占用的时间,已被占用的就跳过。为什么对终点进行排序,因为这样就能够做到不浪费每一秒,对时间进行合理的安排。若对起点进行排序,将有可能使得后面本可以安排的时间都无法安排,例如第一个样例。
代码:
1 #include<iostream> 2 #include<cstring> 3 #include<cstdio> 4 #include<string> 5 #include<cmath> 6 #include<algorithm> 7 #include<stack> 8 #include<queue> 9 #define eps 1e-7 10 #define ll long long 11 #define inf 0x3f3f3f3f 12 #define pi 3.141592653589793238462643383279 13 using namespace std; 14 const int MAXN = 10007; 15 struct node{ 16 int beg,end; 17 }num[105]; 18 19 int cmp(node a,node b) 20 { 21 if(a.end != b.end) 22 return a.end < b.end; 23 else return a.beg < b.beg; 24 } 25 26 bool judge(int n,int len) 27 { 28 int visit[MAXN]; 29 memset(visit,0,sizeof(visit)); 30 for(int i=0; i<n; ++i) //遍历每一个时间段 31 { 32 int cnt = 0; 33 for(int j=num[i].beg; j<num[i].end; ++j) //安排时间,标记占用 34 { 35 if(!visit[j]) 36 { 37 visit[j] = 1; 38 cnt++; 39 } 40 if(cnt == len) break; 41 } 42 if(cnt < len) return false; 43 } 44 return true; 45 } 46 47 int main() 48 { 49 int n; 50 while(cin>>n) 51 { 52 for(int i=0; i<n; ++i) 53 scanf("%d%d",&num[i].beg,&num[i].end); 54 sort(num,num+n,cmp);//排序 55 int low = 0,high = MAXN; 56 while(low <= high) //二分 57 { 58 int mid = (low + high)/2; 59 if(judge(n,mid)) 60 low = mid + 1; 61 else high = mid - 1; 62 } 63 cout<<(high*n)<<endl; //n个时间段,每个都占用了相同大小的一段 64 } 65 return 0; 66 }