【二分答案】洛谷P1182 数列分段

链接

https://www.luogu.org/problemnew/show/P1182

大意

将一段数列分成不超过 m 的段,使得每段的最小的最大值

思路

一般看到最小……最大……什么的基本都用二分

因为最大值要尽量小,所以数据必然具有单调性,所以我们可以通过二分最大值(即最终答案)来求解。中间加上判断即可

代码

#include<cstdio>
using namespace std;int l,r,mid,a[100001],s,n,m;
inline bool check(register int sum)//判断
{
    int j=1;
    for(register int i=1;i<=m;i++)//分成的段数
    {
        for(register int sm=a[j];sm<=sum;sm+=a[++j])//当和没有超过枚举的数时继续
        if(j>n) return true;//若可以一直加下去,说明已经可以满足条件了
    }
    return j>n;//看到最后能否满足条件
}
signed main()
{
    scanf("%d%d",&n,&m);
    for(register int i=1;i<=n;i++) scanf("%d",a+i),s+=a[i];
    r=s;
    while(l<=r)
    {
        mid=(l+r)>>1;
        if(check(mid)) r=mid-1;else l=mid+1;//二分
    }
    printf("%d",r+1);//因为r每次都为mid-1,且本题一定有解,故输出mid,即r+1
}

猜你喜欢

转载自blog.csdn.net/xuxiayang/article/details/81630385