码迷,mamicode.com
首页 > 其他好文 > 详细

CODEVS2744 养鱼喂妹子 - 二分+贪心

时间:2018-08-04 21:41:04      阅读:138      评论:0      收藏:0      [点我收藏+]

标签:long   turn   else   pac   problem   log   int   tar   遍历   

传送门

思路:加上能够养活x个妹子,那么必定能养活<x个妹子,满足单调性,可以二分。

我们二分能够养活的最大的妹子数量。对于当前已经符合check函数的mid,ans一定在[mid,r]的区间内,

因此采用 mid=(l+r+1)>>1;if(check(mid)) l=mid;else r=mid-1; 最终答案为 l-1。

关于check函数,我们用一种类似均分纸牌的做法:遍历每个城镇,若当前城镇缺鱼,就向右边要;注意,若当前城镇多鱼,你能给右边不就给吗。。。

最后看下最后一个城镇是否缺鱼。

tips:二分边界要搞好,可以直接[0,+inf],毕竟人家是O(logn)。

AC Code:

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int N=100000+10;
typedef long long ll;
ll pos[N],a[N],b[N];
int n;
bool check(ll mid){
    for(int i=1;i<=n;i++) b[i]-=mid;
    for(int i=1;i<n;i++){
        if(b[i]<0) b[i+1]-=abs(b[i])+abs(pos[i+1]-pos[i]);
        else if(b[i]>pos[i+1]-pos[i]) b[i+1]+=b[i]-(pos[i+1]-pos[i]);
    }
    return b[n]>=0; 
}
int main(){
    scanf("%d",&n);
    for(int i=1;i<=n;i++){
        scanf("%lld%lld",&pos[i],&a[i]);
    }
    ll l=0,r=1<<30;//!!
    while(l<r){
        memcpy(b,a,sizeof(a));
        ll mid=(l+r+1)>>1;
        if(check(mid)) l=mid;
        else r=mid-1;
    }
    printf("%lld",l);
    return 0;
}

 

CODEVS2744 养鱼喂妹子 - 二分+贪心

标签:long   turn   else   pac   problem   log   int   tar   遍历   

原文地址:https://www.cnblogs.com/Loi-Brilliant/p/9419933.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!