算法思路:首先求最大值最小或最小值最大问题应用二分来直接二分出答案,其次写出check函数判断,由题意可得,答案的范围一定在数列的最大值至数列所有项的和之间,于是我们可令l = 数列中最大值, r = 数列所有项的和,而check函数应判断我们二分到的答案最少能分为几段,如果段数大于m则答案在mid右侧,否则答案在mid左侧。
AC代码
#include <iostream>
#include <algorithm>
using namespace std;
const int N = 100010;
int a[N], s[N], n, m;
int check(int x)
{
int res = 1, sum = 0;
for(int i = 1; i <= n; i++)
{
sum += a[i];
if(sum > x) res++, sum = a[i];
}
return res;
}
int main(void)
{
int l = 0, r;
cin >> n >> m;
for(int i = 1; i <= n; i++)
{
cin >> a[i];
l = max(l, a[i]);
s[i] = s[i-1] + a[i];
}
r = s[n];
while(l < r)
{
int mid = l + r >> 1;
if(check(mid) > m) l = mid + 1;
else r = mid;
}
cout << l << endl;
return 0;
}