给出一个大小为N的数组,将其分为M块,让每块数字之和的最大值尽量小。右边界是将整个数组当做一块,那么最大值就是所有数字之和;左边界是将整个数组分成N块,那么和的最大值就是数组元素中的最大值。其实,当给出一个答案后,从数组首元素开始叠加,超出答案那么分块数加1,这么遍历一遍后,要是分块数小于M,说明答案给的大了,反之答案给小了。
代码如下
#include<stdio.h>
#include<string.h>
#define MAXN 100005
int expense[MAXN];
int N,M;
void main()
{
int i,mid,cnt;
int max=0,sum=0;
int left,right;
scanf("%d%d",&N,&M);
for (i=1;i<=N;i++)
{
scanf("%d",&expense[i]);
sum+=expense[i];
if(expense[i]>max)
max=expense[i];
}
left=max;
right=sum;
while(left<right)
{
sum=0;
cnt=0;
mid=(left+right)/2;
for(i=1;i<=N;i++)
{
sum+=expense[i];
if(sum>mid)
{
cnt++;
sum=0;
i--;
continue;
}
}
cnt++;
if(cnt>M)
left=mid+1;
else
right=mid-1;
}
printf("%d\n",left);
}