贪心判断和之前最大化最小值的题目思路类似,只不过需要小心分组数;
二分(注意这是最大值最小化而不是最小值最大化)
1.注意判断函数最后return的条件和主函数二分的通用写法!不然莫名WA很难受。
2.注意先算出上下界
#include <iostream>
#include<stdio.h>
#include<algorithm>
using namespace std;
int L,M,N;
int a[5000010];
bool Judge(int s)//最小和
{
int i=0;
int zu=1;
int temp=0;
for(int i=0;i<N;i++)
{
if(temp+a[i]<=s)//划分组关键是组头划还是组尾划,此处从组头开始判断
{
temp+=a[i];
}
else
{
temp=a[i];
zu++;
}
}
// cout<<s<<"?"<<cu<<endl;
if(zu>M)//不能加等于号,会WA,意义千差万别
return true;
else //要特判等号的情况→ 就算等于,还想找更小的 ,所以往左找
return false;
}
int main()
{
cin>>N>>M;
int max2=0;
int sum1=0;
for(int i=0;i<N;i++)
{
scanf("%d",&a[i]);
sum1+=a[i];
max2=max(a[i],max2);
}
int l=max2;
int r=sum1;//上下界必须确定好
int mid;
while(l<=r) //这里条件写法很多种
{
mid=(l+r)/2;
if(Judge(mid))
l=mid+1;//换了种写法,这种写法适用性强
else
r=mid-1;
}
cout<<l<<endl;
}