1. 程式人生 > >王曉東 獨立任務最優排程問題

王曉東 獨立任務最優排程問題

方法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