【二分】抄书 (jzoj 2123)

版权声明:欢迎借鉴,谢绝抄搬。 https://blog.csdn.net/ssllyf/article/details/86670465

抄书

题目大意:

有n本书,分给m个人抄,每个人只能拿到连续的书(不能把一本书分开),问抄书最多的人要抄多少页

样例输入

9 3

100 200 300 400 500 600 700 800 900

样例输出

1700

数据范围限制

对于10%的数据,有N<=10

对于50%的数据,有N<=500;

对于100%的数据,有N<=3000;

解题思路:

这道题很可能想到DP但会炸,我们要用二分枚举答案,然后用一冲循环来把书分配给每个人

#include<cstdio>
#include<iostream>
#include<cstring>
using namespace std;
int n,m,num,maxn,l,r,mid,p,w,b[3005],a[3004];
int main()
{
	scanf("%d %d",&n,&m);
	for (int i=1;i<=n;i++)
	  {
	  	scanf("%d",&a[i]);
	  	maxn+=a[i];//求总值
	  	num=max(num,a[i]);//求最大的
	  }
	l=num;//最小的
	r=maxn;//最大的
	while(l<=r)
	{
		mid=(l+r)/2;//二分
		p=1;
		memset(b,0,sizeof(b));//清零
		w=1;
		for (int i=1;i<=n;i++)
		  if (b[w]+a[i]<=mid) b[w]+=a[i];//没有大于当前枚举的结果
		  else 
		  {
		  	if (w==m)//若没人了,就是没有解
		  	{
		  		p=0;
		  		break;
			}
			b[++w]+=a[i];//有人就换一个人
		  }
		if (p) r=mid-1;//二分
		else l=mid+1;//二分
	}
	printf("%d",l);
	return 0;
}

猜你喜欢

转载自blog.csdn.net/ssllyf/article/details/86670465