最大值最小化(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;
}

 

posted @ 2018-04-28 10:23  频窗听雪  阅读(867)  评论(0)    收藏  举报