二分答案:将最值问题转化成为一个判定问题,即选择一个x,看是否符合要求,若符合,则左边的都符合,可以去右边寻找,否则去左边寻找。有一个check函数和二分查找构成
#include<bits/stdc++.h>
#define MAX 100001
using namespace std;
using gg=long long;
gg n,m;
gg arr[MAX];
gg arr_sum[MAX];
gg res;
bool check(gg mid)
{
gg sum=0;
gg num=0;
for(gg i=0;i<n;i++)
{
if(sum+arr[i]>mid)//这里要用sum+arr[i]不能用sum>mid去判断
{
sum=0;
num++;
}
sum+=arr[i];
}
return num>=m;
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(NULL);
cin>>n>>m;
gg sum=0;
gg left = 0;
for(gg i=0;i<n;i++)
{
cin>>arr[i];
left = max(left,arr[i]);
sum+=arr[i];
arr_sum[i]=sum;
}
gg right = arr_sum[n-1];
//cout<<left<< " "<<right<<endl;
//当分段数大于规定值说明可以大一点,否则小一点
while(left<=right)
{
gg mid = (left+right)/2;
if(check(mid))
{
res = mid;
left = mid+1;//当前值的左边都可以,试一试当前值的右边
}
else
{
right=mid-1;//当前值的右边都不行,去左边找答案
}
}
cout<<left<<endl;
return 0;
}