要求:n个数组成的序列,分为m个区间,求区间和的最小化的最大值。
1<=n<=100000,1<=m<=n,n个数均是不超过10000的正整数。
方法:二分答案满足中间条件。
其实二分就是二分答案去满足条件,以前比较迷糊,看了这个题才清楚点。
1.答案的最小值是n个数的最大值,答案的最大值是n个数的和。可以用二分枚举答案,然后通过答案去判断区间数是否为m。
2.能用二分的条件是答案相对于区间数是单调的,区间数越多,答案越小,区间数越少,答案越大。
3.最后输出l、r还是mid需要自行判断,这个题若judge返回cnt<m,l=mid+1,最后输出l。
#include<stdio.h>
#include<math.h>
#include<string.h>
#include<algorithm>
using namespace std;
int n,m,a[100001];
bool judge(int mid)
{
int i,j,k,sum=0,cnt=0;
for(i=0;i<n;i++)
{
while(i<n&&sum+a[i]<=mid)
{
sum+=a[i];
i++;
}
i--;
cnt++;
sum=0;
}
return cnt>m;
}
int main()
{
int i,j,k,max1=-1,sum=0,l,r,mid;
scanf("%d%d",&n,&m);
for(i=0;i<n;i++)
{
scanf("%d",&a[i]);
sum+=a[i];
max1=max(max1,a[i]);
}
l=max1,r=sum;
while(l<=r)
{
mid=(l+r)/2;
if(judge(mid)) l=mid+1;// mid比较小 导致区间比较多
else r=mid-1;
}
printf("%d\n",l);
}