最大值最小化(maxmin)
分析:给定序列后,我们可以知道任意划分的最大值的取值范围[0, sum(1...n)],一种较慢的方法是枚举每种取值情况,根据枚举值进行序列划分,若划分的组数大于m,说明没有满足条件的划分情况,需要增加枚举值;如果划分的组数小于m,说明找到了满足条件的划分情况。时间复杂度为O(n*sum);
思路扩展:既然找到了线性的枚举方法,我们不妨考虑下二分枚举的方法,考虑mid的情况是否满足条件,如何划分组数大于m,与线性枚举的情况相同;若划分的组数小于m,说明当前解满足条件,但可能还有比当前解还小的解,需进一步计算。
#include<cstdio>
void read(int &x)
{
x=0;int f=0;char ch=getchar();
while(ch<'0'||ch>'9') {f|=(ch=='-');ch=getchar();}
while(ch>='0'&&ch<='9') {x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}
x=f?-x:x;
return;
}//读入优化
int a[1000005],n,m;
int main()
{
read(n),read(m);
int sum=0;
for(int i=0;i<n;i++)
{
read(a[i]);
sum+=a[i];
}
int l=a[0],r=sum,mid;
while(l<r)
{
mid=(l+r)/2;
int ans=1,uadd=0;
for(int i=0;i<n;i++)
{
if(uadd+a[i]>mid)
uadd=a[i],ans++;
else
uadd+=a[i];
}
if(ans>m)
l=mid+1;
else
r=mid;
}
printf("%d",l);
return 0;
}

浙公网安备 33010602011771号