Solution:
这道题让我们将数列分组,分成m组,并且求出每组的和,使每组和中的最大值最小,遇到这种我们,就要想到用二分的思想。关键就是我们怎样确定二分的范围,我们最多把数列分为n组,每组只有一个元素,找出所有元素的最大值max;最少把数列分为1组,也就是不分组,这组的和就是n个元素的和sum。而我们要求的就在max~sum之间。
代码如下:
#include<iostream>
#include<math.h>
#define MAX 100005
using namespace std;
int n,m;
int a[MAX];
bool judge(int mid){
int cnt=0;//已经分的组数
int sum=0;//每一组的总和值
for(int i=0;i<n;i++){
if(sum+a[i]<=mid){//若每组的值仍然小于等于试探的值,则继续向组里添加元素
sum+=a[i];
}else{//否则,就新增加一个组
sum=a[i];
cnt++;
}
}
if(cnt>=m){//如果已经超过了最大组数限制,就返回false
return false;
}else{//否则,返回true
return true;
}
}
int main(){
cin>>n>>m;
int left=-1,right=0,mid;
for(int i=0;i<n;i++){
cin>>a[i];
left=max(a[i],left);//left为数组中的最大值
right+=a[i];//right为所有元素的和
}
while(left<=right){//二分查找
mid=(left+right)/2;
if(judge(mid)==true){//若mid的值在满足分组的情况下偏大
right=mid-1;
}else{//若mid的值偏小,不能满足分组
left=mid+1;
}
}
cout<<left;//left即为最后的值
return 0;
}