渔民的烦恼
题目描述
- 在某个海边小国,大多数居民都是渔民,这个国家的所有城镇都沿直线分布在海边。渔民们捕获大量的海鱼,但就象世界上大多数的渔民一样,他们并不喜欢吃鱼,所以他们决定从邻国收养一些贫困家庭的小孩,让他们来帮着吃鱼,国家规定每个城镇收养的贫困儿童数量必须相等。
- 一条又长又直的公路贯穿整个海岸将所有的城镇连接了起来,所以每个城镇(除去第一个和最后一个)都直接和相邻的两个城镇相连接。一个小孩一年要吃掉一吨鱼,每个城镇捕获的鱼既可以在本地吃也可以运往其它城市吃,在运输过程中,每公里要上交一吨鱼作为过路费。
- 已知每个城镇一年的捕鱼产量,并假设运输方案是最佳的,计算最多能收奍多少个贫困儿童。
输入格式
输出格式
输出文件仅一行,包含一个整数表示每个城镇最多能够收养的贫困儿童数量。
样例
样例输入
4
20 300
40 400
340 700
360 600
样例输出
415
题解
- 明显的二分板子,细节很多,需要注意!!!
code
/*
4
20 300
40 400
340 700
360 600
*/
/*
415
*/
#include<bits/stdc++.h>
using namespace std;
const int maxn=1e5+10;
long long pos[maxn],v[maxn];
long long n;
bool check(long long sum){
long long fish=0;
for(int i=1;i<n;++i){
long long cnt=v[i] + fish;
if(cnt < sum)
fish=cnt-sum-(pos[i+1]-pos[i]);
else {
fish=cnt-sum-(pos[i+1]-pos[i]);
if(fish < 0)fish=0;
}
}
if(v[n]+fish>=sum)return true;
return false;
}
int main(){
cin>>n;
long long Max=0;
for(int i=1;i<=n;++i){
cin>>pos[i]>>v[i];
Max=max(Max,v[i]);
}
long long l=0;
long long r=Max;
while(l <= r){
int mid=(l+r)>>1;
if(r-l == 1){
if(check(r))l=r;
cout<<l;
return 0;
}
if(check(mid))l=mid;
else r=mid;
}
cout<<l;
return 0;
}