经典题目,具体不解释……
算法:DP
分析:因为是让两台机器工作,因此设立DP方程的时候我们都要兼顾,设t[j]=min{t[j-a[i]],t[j]+b[i]},t[i]表示A机器工作i时间,B机器工作的最少时间是t[i]时间,这样的话就形成了对应。第i件工作如果由A做,那么就是t[j-a[i]];同理,如果让B做,那么就是t[j]+b[i],即B的工作时间要延长。
因此,我们可以看到,当题目中要求的两个状态有某些关联的话,其状态转移方程一定也有一定的对应关系,即通过A的可以间接的确定B的,这是一种很重要的思想和方法。
program sched;
const
maxn=200;
maxm=20000;
var
n,sa:longint;
a,b:array [0..maxn] of longint;{a[i]表示在A机器上的工作时间,同理b[i]表示在B机器上的工作时间。}
t:array [0..maxm] of longint;
procedure init;
var
i:longint;
begin
readln(n);
for i:=1 to n do
begin
read(a[i]);
inc(sa,a[i]);{我们要增加A的工作总时间,以确定A的最大工作时间,即所有任务全让A做。}
end;
for i:=1 to n do read(b[i]);
end;
function min(x,y:longint):longint;
begin
if x<y then exit(x) else exit(y);
end;
function max(x,y:longint):longint;
begin
if x>y then exit(x) else exit(y);
end;
procedure main;
var
i,j,k,minn:longint;
begin
for i:=1 to n do
begin
for j:=sa downto 0 do
begin
if j>=a[i] then t[j]:=min(t[j-a[i]],t[j]+b[i]) else t[j]:=t[j]+b[i];{如果当前的时间足以让A工作,就让A工作,否则让B工作。}
end;
end;
minn:=maxlongint;
for i:=0 to sa do{比较同时间在A工作和在B工作上谁用的时间长,最大值的最小值就是我们要求的答案。}
begin
k:=max(i,t[i]);
if k<minn then minn:=k;
end;
writeln(minn);
end;
begin
assign(input,'sched.in'); reset(input);
assign(output,'sched.out'); rewrite(output);
init;
main;
close(input); close(output);
end.