链接
https://www.luogu.org/problemnew/show/P1182
大意
将一段数列分成不超过 的段,使得每段的最小的最大值
思路
一般看到最小……最大……什么的基本都用二分
因为最大值要尽量小,所以数据必然具有单调性,所以我们可以通过二分最大值(即最终答案)来求解。中间加上判断即可
代码
#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
}