ZCMU - 2154: E.wjw的排队问题

题目链接:点击打开链接


题目大意:略。


解题思路:二分 + 贪心。明显可以看出此题的答案具有单调性(单调性解释:比如说如果题目的答案为3,那么4也符合题目要求只不过不是最优解罢了)因为答案具有单调性,于是可以采用二分的方式求解答案。
答案检验。比如说如果当前检验答案为mid,那么对于第i个团体可以分散的范围为[b[i]-mid,b[i]+mid],只要当前范围剩余空位小于a[i],则表示当前答案一定是不可行解。那如何分散人呢?尽量将人分散到可行区间的左边或右边(单侧边即可)!


AC 代码

#include<bits/stdc++.h>
#include<cmath>

#define mem(a,b) memset(a,b,sizeof a)
#define INF 0x3f3f3f3f

using namespace std;

typedef long long ll;
const int maxn=100000+100;
int a[maxn],b[maxn];
int n;

int ok(int m)
{
    int len=b[1]-m;
    for(int i=1;i<=n;i++)
    {
        len=max(len,b[i]-m); // 取前一个排满人数后还剩的空间 与 当前b[i]-m可拥有的空间,两者取最大值
        if(b[i]+m-len+1<a[i]) return 0;
        len+=a[i];
    }
    return 1;
}

int main()
{
    while(~scanf("%d",&n))
    {
        for(int i=1;i<=n;i++) scanf("%d",&a[i]);
        for(int i=1;i<=n;i++) scanf("%d",&b[i]);

        int l=1,m,r=100000000+10;
        while(l<=r) // 注意这里需要等号
        {
            m=l+((r-l)>>1);
            if(ok(m)) r=m-1;
            else l=m+1;
        }
        printf("%d\n",l);
    }

    return 0;
}

猜你喜欢

转载自blog.csdn.net/dream_weave/article/details/80703869
今日推荐