王曉東 獨立任務最優排程問題
方法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