题目大意:
给一个长度为n的数列,并给出要把这个数列分的段数k,问每一段的和的最大值的最小值是多少
思路:因为ai不超过1e9,所以可以二分查找答案,左端点为数列中的最大值,右端点为数列中所有数的和,每次枚举,依次将每个数相加,如果和大于mid,就段数+1,重新求和,最后判断所求段数和需要段数的关系
#include<bits/stdc++.h>
using namespace std;
long long n,m;
long long a[100005];
bool check(long long x)
{
long long duan = 0, sum = 0;
for (int i = 1; i <= n; i++)
{
if (a[i] + sum > x)//如果当前的数字和大于最小值,段数+1,数字和重置为当前遍历到的数
{
duan++;
sum = a[i];
}
else
sum += a[i];
}
return duan >= m;
}
int main()
{
long long l=0,r=0,mid;
cin >> n >> m;
for (int i = 1; i <= n; i++)
{
cin >> a[i];
r += a[i];
l = max(l, a[i]);
}
while (l <= r)
{
mid = (l + r) >> 1;
if (check(mid))//如果求得段数比需要的多,就把最大值的最小值高一点
l = mid+1;
else
r = mid-1;//反之就小一点
}
cout << l;
}