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