2013年3月23号竞赛题目一 平衡负载

本文介绍了一个优化算法,用于解决将连续任务分配给多台服务器的问题,目标是最小化完成所有任务所需的最大时间。通过二分查找和贪心策略,算法能在多项式时间内找到最优解。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

平衡负载

Du熊正在负责一个大型的项目,目前有K台服务器,有N个任务需要用这K台服务器来完成,所以要把这些任务分成K个部分来完成,在同上台服务器上执行的任务必须是连续的任务,每个任务有各自需要的执行时间。

例如N=5,K=2,每个任务需要时间分别为5,3,1,4,7分钟,那么我们可以分成(5)(3 1 4 7)两部分,这样第一台服务器所花时间就是5分钟,而第二台机器需要花15分钟,当然,所有任务完成的时间是按最迟完成的那台服务器的时间,即这样划分的话完成所有任务所需要的时间就是15分钟。而另外一种划分方法是(5 3 1)(4 7),这种划分方案完成所有任务的时间就是11分钟,也是最优的一种划分方案。

现在你的任务就是根据给定的N,K和每个任务要花费的时间,找出使完成所有任务时间最短的方案。

 

输入:

多组输入。

第一行输入N和K(1<=K<=N<=10000)。

第二行输入N个不大于1000的正整数,表示各个任要花费的时间。

N=K=0表示输入结束。

 

输出:

每行输出一个整数,对应对于每个数据(除了N=K=0不用输出)。

 

样例输入:

 

5 1
5 3 1 4 7
5 2
5 3 1 4 7
5 3
5 3 1 4 7
10 3
1 2 3 4 5 6 7 8 9 10
0 0

 

样例输出:

 

20
11
8
21

分析:给定一个长度为n的数列,分成连续的k段,使k段和中的最大值最小
#include<cstdio>
int sum(int A[],int from,int to){ 
	int total=0,i; 
	for(i=from;i<=to;i++)total+=A[i]; 
	return total; 
} 
int getMax(int A[],int n){ 
	int max=0,i; 
	for(i=0;i<n;i++){ 
		if(A[i]>max)max=A[i]; 
	} 
	return max; 
} 
int getSum(int A[],int n){ 
	int total=0,i; 
	for(i=0;i<n;i++)total+=A[i]; 
	return total; 
} 
int cal(int A[],int n,int m){ 
	int total=0,num=1; 
	for (int i=0;i<n;i++) { 
		total+=A[i]; 
		if(total>m){ 
			total=A[i]; 
			num++; 
		} 
	} 
	return num; 
} 
int BS(int A[],int n,int k){ 
	int l=getMax(A,n); 
	int h=getSum(A,n); 
	while(l<h){ 
		int m=l+(h-l)/2; 
		int res=cal(A,n,m); 
		if(res<=k)h=m; 
		else l=m+1; 
	} 
	return l; 
}
int a[10002];
int main()
{
	int n,k,i;
	while(~scanf("%d%d",&n,&k)){
		if(n==0&&k==0)break;
		for(i=0;i<n;i++)scanf("%d",&a[i]);
		printf("%d\n",BS(a,n,k));
	}
	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值