要求n个数分成m组,组内元素之和的最大值最小,显然二分。
我们就二分要求的这个值x,我们每次check的时候就都把这n个数分成cnt组,组内元素之和sum应小于等于x,然后根据cnt和m的关系,进行l的右移或者r的左移。
#include<bits/stdc++.h>
#define ll long long
#define linf 0x3f3f3f3f3f3f3f3f
using namespace std;
const int maxn = 5e4 + 10;
int n,m;
ll a[maxn];
bool ck(ll x){
ll sm = 0;
int cnt = 0;
for(int i = 1;i <= n;i++){
sm += a[i];
if(sm >= x){
sm = a[i];
cnt++;
}
}
return cnt < m;
}
int main(){
scanf("%d%d",&n,&m);
for(int i = 1;i <= n;i++){
scanf("%lld",&a[i]);
}
ll l = 1,r = linf;
while(l < r){
ll mid = (l + r + 1) / 2;
if(ck(mid)){
r = mid - 1;
}
else {
l = mid;
}
}
printf("%lld\n",l);
return 0;
}