王晓东 独立任务最优调度问题

方法1:


#include "stdio.h"
#include "string.h"

#define MX 10
#define MAX(a, b) ((a)>(b)?(a):(b))
#define MIN(a, b) ((a)<(b)?(a):(b))

int a[MX], b[MX];
int T[100][100][MX];
int n;

void main(){
	int i, j, k;
	int ta, tb;
	int ans;
	freopen("in.txt", "r", stdin);
	while(scanf("%d", &n), n){

		ta = tb = 0;
		for(i=1; i<=n; i++){
			scanf("%d", a+i);
			ta += a[i];
		}
		for(i=1; i<=n; i++){
			scanf("%d", b+i);
			tb += b[i];
		}
		
		memset(T, 0, sizeof(T));
		T[0][0][0] = 1;
		for(k=1; k<=n; k++)
			for(i=0; i<=ta; i++)
				for(j=0; j<=tb; j++){
					if(i>=a[k]&&T[i-a[k]][j][k-1])
						T[i][j][k] = 1;
					if(j>=b[k]&&T[i][j-b[k]][k-1])
						T[i][j][k] = 1;
				}

		ans = 0x7FFFFFFF;
		for(i=0; i<=ta; i++)
			for(j=0; j<=tb; j++)
				if(T[i][j][n])
					ans = MIN(ans, MAX(i, j));
		printf("%d\n", ans);
	}
}


-----------------------------------****************************************---------------------------------*******************************************

方法2:



T[i][k] 表示:完成K个任务,注意,是完成!不论这K个任务在A,B两个处理机上怎么分配。当处理完这K个任务后,在A处理机花费时间小于等于i时,B处理器花费的最小时间。

例如,当A处理机花费时间等于0,即A没有参与K个任务的处理,所有的任务都交给了B来做,这样,B处理机花费的时间就是K个任务的时间和,∑b[i] (1<=i<=k)。表示出来就是 T[0][k] = ∑b[i]。



状态转移方程:

T[i][k] = MIN(   T[i-a[k]][k-1],     T[i][k-1]+b[k]        )

T[i-a[k]][k-1]:完成K-1个任务,A处理机花费时间小于等于i-a[k]时,B处理机花费的最小时间。假如将第K个任务交给A处理机来做,B处理机不动,这样完成K个任务时,A处理机花费的时间小于等于 (i-a[k])+a[k] = i,而B处理机没动,所以

T[i][k] = T[i-a[k]][k-1],直接将完成K-1个任务时这个时间复制给完成K个任务的最小时间(因为第K个任务是A处理机做的,B处理机休息了,没花费时间)

T[i][k-1]:完成K-1个任务,A处理机花费时间小于等于i时,B处理机花费的最小时间。假如将第K个任务交给B处理机来做,A处理机不动,这样完成K个任务时花费的时间,就应该是:完成K-1个任务,A处理机花费时间小于等于i时,B处理机花费的时间,再加上第K个任务在B处理机上花费的时间,即 T[i][k] = T[i][k-1] + b[k]


这样,到底是将第K个任务放在A上处理好还是B上处理好呢?不管放在哪个处理机上处理,最后都完成了K个任务。时间就应该取两种选择的最小值。


这第二种的想法与第一种不同,理解来有点乱,我也是想了好久才想通。在看第二种方法时,只要给自己强制一种想法,T[i][k]就是表示已完成K个任务时,A花费的时间小于等于i时,B处理机花费的最小时间。我管你K个任务是怎么在A,B上分配的,反正就是完成了,并得到此时B花费的最小时间。再想想,A和B是一起来处理K个任务,A分担的多一点,B自然需要的时间就少了,但是只给A处理机i的时间,A要在i的时间内完成最多的任务,这样B处理机就轻松了,消耗的时间就少。当然,我给A处理机i的时间,A可以不理睬,A就闲着,让B去做。当然,最后T[i][k]会取到最优的值,即A充分利用这i的时间来完成任务,让B消耗的时间达到最小。


状态转移方程只涉及到k和k-1行,所以可以压缩空间。但是要注意第二层for循环的顺序是从大到小,避免覆盖。

#include "stdio.h"
#include "string.h"

#define MX 10
#define MAX(a, b) ((a)>(b)?(a):(b))
#define MIN(a, b) ((a)<(b)?(a):(b))
int a[MX], b[MX];
int T[100];
int n;

void main(){
	int i, k;
	int ta, ans;
	freopen("in.txt", "r", stdin);
	while(scanf("%d", &n), n){
		ta = 0;
		for(i=1; i<=n; i++){
			scanf("%d", a+i);
			ta += a[i];
		}
		for(i=1; i<=n; i++) scanf("%d", b+i);

		memset(T, 0, sizeof(T));
		for(k=1; k<=n; k++)
			for(i=ta; i>=0; i--)
				if(i>=a[k])
					T[i] = MIN(T[i-a[k]], T[i]+b[k]);
				else
					T[i] = T[i]+b[k];

		ans = 0X7FFFFFFF;
		for(i=0; i<=ta; i++)
			ans = MIN(ans, MAX(i, T[i]));

		printf("%d\n", ans);


	}
}

原地址: http://hi.baidu.com/dengwnp/blog/item/8cc8ec0abff68e9e0b7b82ac.html
  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值