二分答案

                                                                                                               渔民的烦恼

题目描述

  •  在某个海边小国,大多数居民都是渔民,这个国家的所有城镇都沿直线分布在海边。渔民们捕获大量的海鱼,但就象世界上大多数的渔民一样,他们并不喜欢吃鱼,所以他们决定从邻国收养一些贫困家庭的小孩,让他们来帮着吃鱼,国家规定每个城镇收养的贫困儿童数量必须相等。
  • 一条又长又直的公路贯穿整个海岸将所有的城镇连接了起来,所以每个城镇(除去第一个和最后一个)都直接和相邻的两个城镇相连接。一个小孩一年要吃掉一吨鱼,每个城镇捕获的鱼既可以在本地吃也可以运往其它城市吃,在运输过程中,每公里要上交一吨鱼作为过路费。
  • 已知每个城镇一年的捕鱼产量,并假设运输方案是最佳的,计算最多能收奍多少个贫困儿童。

输入格式

  • 第一行包含一个整数N,其中1<=N<=100,000,表示城镇总数。
  • 接下来的N行每行包含两个整数A和B,其中1<=A<=1,000,000,000,0<=B<=1,000,000,000,分别表示城镇的位置(坐标)和该城镇的捕鱼产量,所有城镇按其位置从小到大排序给出,注意问题一定存在正整数解。

输出格式

输出文件仅一行,包含一个整数表示每个城镇最多能够收养的贫困儿童数量。

样例输

4

20 30

40 400

340 700

360 600

样例输出

415
思路:因为A,B范围较大,二分答案
 1 #include<cstdio>
 2 #include<algorithm>
 3 using namespace std;
 4 const int maxn=100000+10,inf=0x3f3f3f3f;
 5 typedef long long ll;
 6 int a[maxn],b[maxn];
 7 int n,mx=0,mn=inf;
 8 bool check(int x){
 9     ll follow=0;
10     for(int i=1;i<n;i++){
11         ll y=b[i]+follow;
12         if(y<x){
13             follow=y-x+(a[i]-a[i+1]);//向后边借
14         }        
15         else{
16             follow=y-x-(a[i+1]-a[i]);//向后边送
17             if(follow<0) follow=0;//若多出的不够路费,不送
18         }
19     }
20     return b[n]+follow>=x;//判断最后是否符合要求,因为前面操作确保1到n-1符合
21 }
22 void solve(){
23     int l=mn,r=mx;
24     while(l<r){//不能写l<=r,可能会死循环,若l==4,r==4,mid==4符合,r==4,有=,l一直等于4
25         int mid=(l+r+1)>>1;//+1避免死循环
26         if(check(mid)) l=mid;
27         else r=mid-1;        
28     }
29     printf("%d\n",l);
30 }
31 int main(){
32     scanf("%d",&n);
33     for(int i=1;i<=n;i++){
34         scanf("%d%d",&a[i],&b[i]);
35         mn=min(mn,b[i]);
36         mx=max(mx,b[i]);//求出二分范围
37     }
38     solve();
39     return 0;
40 }
View Code

 

 
posted @ 2020-07-19 14:49  ddoodd  阅读(143)  评论(0编辑  收藏  举报