这又是一道试了半天没过
最后学习了dalao们的题解才A的题
主要参考博客地址
思路:
答案肯定是数组中最大的数和数组中和之间的某一个数,因此就可以用二分法去找到那个数,更详细的思路见下面代码
其中,二分搜索用到的三个变量中:
left:储存二分搜索区间中最小的数(在这道题就是数组中最大的数)
right:储存二分搜索区间最大的数(在这道题中就是数组总和)
代码:
#include<bits/stdc++.h>
using namespace std;
int n, m;
int a[100500];
int check(int x){ //该函数是检查能否划分m个区间, 区间最大值为x
int sum = 0, cnt = 1; //sum记录每个划分区间的和, cnt记录划分区间的个数
for(int i=1; i<=n; i++){
if(sum+a[i]<=x) //如果sum+a[i]值还小于等于x, 则加上a[i]
sum += a[i];
else //如果sum+a[i]值大于x, 区间数+1, 新区间的和sum为a[i]
sum = a[i], cnt++;
}
return cnt<=m; //通过一轮划分,如果区间数小于等于m, 证明区间最大值x是可行的, 返回1
}
int main(){
int left, right, mid; //二分要用到的变量
cin>>n>>m;
for(int i=1; i<=n; i++){
cin>>a[i];
left = left>a[i]?left:a[i]; //找到数组中最大的数
right += a[i]; //计算数组总和
}
while(left<=right){ //开始二分搜索
mid = (left+right)/2;
if(check(mid)) //检查mid作为区间最大值是否可行
right = mid - 1; //可行的话, 看看能不能有更小的数可以作为区间最大值
else
left = mid + 1; //不行的话, 只能往更大的数找
}
cout<<left<<endl;
return 0;
}