题意:给 N 个数,划分为 M 个块(不得打乱数顺序)。找到一个最好的划分方式,使得块中的最大值最小。
二分的 l 是 N 个数的最大值,r 是 N 个数的和。
对于每个 mid 贪心遍历,看能否满足条件。
#include<iostream>
#include<cmath>
#include<queue>
#include<cstring>
#include<string>
#include<map>
#include<stack>
#include<set>
#include<cstdio>
#include<algorithm>
using namespace std;
int n, m;
int a[100005];
bool judge(int x){
int pre = 0;
int cnt = 0;
for(int i = 1; i <= n; i++){
if(a[i]-a[pre] > x){
cnt++;
pre = i-1;
i--;
}else if(i==n){
cnt++;
}
}
if(cnt <= m)
return 1;
else return 0;
}
int main(){
//freopen("a.txt", "r", stdin);
while(scanf("%d%d", &n, &m) != EOF){
int maxx = 0, k;
a[0] = 0;
for(int i = 1; i <= n; i++){
scanf("%d", &k);
a[i] = a[i-1]+k;
maxx = max(maxx, k);
}
int l = maxx, r = a[n];
while(l <= r){
int mid = l+(r-l)/2;
if(judge(mid))
r = mid-1;
else
l = mid+1;
}
cout << l << endl;
}
return 0;
}