问题
https://vjudge.net/problem/UVALive-4725
分析
最大最小值,二分法
参考:https://blog.csdn.net/hyczms/article/details/44105403
这题主要难在check函数如何写,学到了,记录离开数量时要加一个cnt记录日期对应的离开量,这样就能使得w,e平衡了,可以统合wsum,wleave,esum,eleave的关系
代码有问题,半天没找到问题在哪,后来发现评测出错了
#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <map>
#include <string>
#include <vector>
#include <algorithm>
using namespace std;
typedef long long LL;
const int maxn=5000+5;
int n,kase=0,w[maxn],e[maxn];
//累计能够离开的飞机的数量
bool check(int x){
int eleave=0,wleave=0,cnt=0,esum=0,wsum=0; //cnt记录能离开的总数
for(int i=0;i<n;++i){
if(e[i]>x || w[i]>x) return false;
esum+=e[i];
wsum+=w[i];
if(esum>x){
int t=min(esum-x,min(eleave,cnt));
eleave-=t;
cnt-=t;
esum-=t;
if(esum>x) return false;
}
if(wsum>x){
int t=min(wsum-x,min(wleave,cnt));
wleave-=t;
cnt-=t;
wsum-=t;
if(wsum>x) return false;
}
if(esum>eleave) eleave++;
if(wsum>wleave) wleave++;
if(esum+wsum>cnt) cnt++;
}
return true;
}
int main(void){
scanf("%d",&kase);
while(kase--){
scanf("%d",&n);
int L=1,R=10000000;
for(int i=0;i<n;++i){
scanf("%d%d",&w[i],&e[i]);
}
//从1开始,0开始后面的不容易写
while(L<R){
int mid=(L+R)>>1;
if(check(mid)) R=mid;
else L=mid+1;
}
printf("%d\n",L-1);
}
}