【二分答案】买礼物的艰辛

小X同学给小C同学选了N件礼物,决定顺序购买并赠送,但作为一个没有工资没有零花钱的可怜小朋友,有M位好心的同学伸出了援助之手,然而为了减少最高的借款量,小X同学希望OI竞赛的你为他合理规划,使得他能轻松快乐地送出礼物。

Input

第一行输入两个用空格隔开的正整数N和M
以下N行每行一个不超过10000正整数,依次表示礼物的价格。

Output

一个整数,即最高借款量。


题目有bug,然而实际上是m+1个人,然后我就A了。。。
答案的范围在最大的a[i]到所有a[i]的和之间,然后二分mid。
按顺序取,如果能借mid或mid以内的钱话r=mid,否则l=mid+1
输出答案。

#include
#include
using namespace std; 
int n,m,a[100001],l;
long long r,mid;
int main(){
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;++i){
		scanf("%d",&a[i]);
		r+=a[i];
		l=max(l,a[i]);
	}
	++m;
	while(l<r){       //二分
		mid=(l+r)/2;
		long long s=0,k=0,lq=0,lr=0;
		while(k<n){   
			++k;   //取到第k个
			if(lq+a[k]<=mid) lq+=a[k];   //累计取了多少,然后有没有超过
			else{   //如果超过了,那么就把这些礼物结算给一个人
				lr++;   //多一个人要借
				lq=0;   //清下零
				if(lr>m) break;   //如果没人可借,退出
				--k;   //避免跳过计算
			}
		}
		if(lq>0) lr++;   //如果有多余的没结算
		if(lr>m) l=mid+1;   //判断是否借得到
		else r=mid;
	}
	printf("%d",l);
} 

你可能感兴趣的:(暴力/模拟)