题目描述
牛牛有一个n个数字的序列a1a2…an,现在牛牛想把这个序列分成k段连续段,牛牛想知道分出来的k个连续段的段内数字和的最小值最大可以是多少?
示例1
输入
复制
4,2,[1,2,1,5]
输出
复制
4
说明
有3种分法
[1],[2,1,5],数字和分别为1,8,最小值为1
[1,2][1,5],数字和分别为3,6,最小值为3
[1,2,1],[5]数字和分别为4,5,最小值为4
则最小值的最大值为4
bool check(int k, int mid, vector<int> &a) {
int temp = 0;
for (int i = 0; i < a.size(); i++)
{
temp += a[i];
if (temp >= mid)
{
k--;
temp = 0;
}
}
//判断是否能分的完
//若k>0则证明可以分的完,则说明极限值过大。
//k<0则表明不可以分完,则说明值过小.
if (k>0)
{
return false;
}
return true;
}
/**
* 分组
* @param n int整型
* @param k int整型
* @param a int整型vector
* @return int整型
*/
int solve(int n, int k, vector<int>& a) {
int right = 0;
for (int i = 0; i < n; i++)
right += a[i];
int left = 0;
//若分为K段 则必然最小值的最大值不超过[0,right]
right /= k;
//则可能存在的分段极限值为[left,right]之间存在.
int mid = (left + right) >> 1;
while (mid > left) {
if (check(k, mid, a))
{
//分段值过小,需增大
left = mid;mid = (left + right) >> 1;
}
else {
//分段值过大,还需减小.
right = mid; mid = (left + right) >> 1;
}
}
if (check(k, right, a))
return right;
else
return left;
}