Uva 714Copying Books,(最大值最小化问题)

题意:

把一个包含N个正整数的序列划分成M个连续的子序列,设第i个序列的总和为Si,求使得Si的最大值最小的划分序列

 

明显的最大值最小化问题。。。

设Si的最大值最小为x,所有数之和为M,二分[0,M]即可求出X的值

 

代码:

 

#include <cstdio>
#include <cstring>
#define LL long long
LL a[1111];

int main()
{
	int t; scanf("%d",&t);
	while(t--)
	{
		int n, m;
		scanf("%d %d",&n,&m);
		LL sum= 0;
		for(int i= 1; i<= n; i++)
		{
			scanf("%lld",&a[i]);
		    sum+= a[i];
		}
		LL L= 0, R= sum;
		while(L< R)
		{
		//	printf("%lld %lld\n",L,R);
			LL mid= (L + R)/ 2; 
			int cnt= 1; //划分次数
			LL s= 0; //当前和 
			for(int i= 1; i<= n; i++)
			{
				if(a[i]> mid)// 当序列有一个数大于mid,表示mid不可行 
				{
					cnt= m+1;
					break;
				}
				s+= a[i];
				if(s> mid)
				{
					cnt++;
					s= a[i];
				}
			}
			if(cnt<= m)
				R= mid;
			else	
				L= mid + 1;		
		}
		int b[555];
		memset(b, 0, sizeof(b));
		LL xx= 0;
		for(int i= n; i>= 1; i--)
		{
			xx+= a[i];
			if(xx> L )
			{
				b[i]= 1;
				xx= a[i];
				m--;
			}
		}
		m--;
		//printf("%d\n",m);
		for(int i= 1; m&& i<= n; i++)
			if(b[i]== 0)
			{
				b[i]= 1;
				m--;
			}
		printf("%lld",a[1]);
		if(b[1])
			printf(" /");	
		for(int i= 2; i<= n; i++)
		{
			printf(" %lld",a[i]);
			if(b[i])
				printf(" /");
		}		
		printf("\n");
	}
	return 0;
}


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值