题目大意:机场上有两个跑道,分别为W和E,每个时刻,W和E都分别都分别有飞机进入跑道,每个跑道的飞机都按顺序从0开始排序,每个时刻都允许一架飞机起飞,现要求你安排起飞的飞机,使得任意时刻的飞机的最大编号最小
解题思路:最小最大值问题,二分进行枚举。先统计一下能起飞的总飞机数和W和E两个跑道能起飞的飞机数,如果该跑道的飞机数超过我们所枚举的飞机数,那么就让其起飞,直到其飞机数小于等于所枚举的飞机数
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
#define maxn 5010
struct plane{
int E, W;
}P[maxn];
int N;
bool check(int cur) {
int sumE = 0, sumW = 0, count = 0, couE = 0, couW = 0;
for(int i = 0; i < N; i++) {
sumE += P[i].E;
sumW += P[i].W;
if(P[i].E > cur + 1 || P[i].W > cur + 1)
return false;
while(sumE > cur + 1) {
if(couE == 0 || count == 0)
return false;
count--;
couE--;
sumE--;
}
while(sumW > cur + 1) {
if(couW == 0 || count == 0)
return false;
count--;
couW--;
sumW--;
}
if(couE < sumE)
couE++;
if(couW < sumW)
couW++;
if(count < sumE + sumW)
count++;
}
return true;
}
int main() {
int test;
scanf("%d",&test);
while(test--) {
scanf("%d",&N);
int MAX = 0;
for(int i = 0; i < N; i++) {
scanf("%d%d",&P[i].E, &P[i].W);
MAX += max(P[i].E, P[i].W);
}
int left = 0 , right = MAX ;
while(left < right) {
int mid = (left + right) / 2;
if(check(mid))
right = mid;
else
left = mid + 1;
}
printf("%d\n",left);
}
return 0;
}