算法:DP(0/1背包)
每一个城堡我们可以看成是一个背包,容积就是高度的和,然后看哪些高度我们可以组成,最后在能满足所有的某个容量的情况下找一个最大值。
program P1190;
const
maxn1=100;
maxn2=10000;
var
n,max:longint;
a:array [0..maxn1,0..maxn1] of longint;{a数组为邻接表,记录每个城堡的积木的高度。}
f:array [0..maxn1,0..maxn2] of boolean;{f[i,j]表示第i个城堡能否组成j高度的城堡。}
procedure main(x,sum:longint);
var
i,j:longint;
begin
f[x,0]:=true;{初始化,高度为0的城堡是可以组成的。}
for i:=1 to a[x,0] do
begin
for j:=sum downto a[x,i] do f[x,j]:=f[x,j] or f[x,j-a[x,i]];{表示组成的0/1背包,看抽掉这块积木或是不抽掉能否组成。}
end;
end;
procedure init;
var
i,j,t,sum:longint;
begin
max:=maxlongint;
readln(n);
for i:=1 to n do
begin
sum:=0;
read(t);
while t<>-1 do
begin
inc(a[i,0]);
a[i,a[i,0]]:=t;
inc(sum,t);
read(t);
end;
if sum<max then max:=sum;{因为所有的背包都要满足,所以容量就要找一个最小的。}
main(i,max);
end;
end;
procedure outit;
var
i,j:longint;
begin
for i:=max downto 1 do
begin
for j:=1 to n do if not f[j,i] then break;
if (j=n) and (f[j,i]) then{找一个最大值。}
begin
writeln(i);
exit;
end;
end;
writeln(0);{不能组成输出0。}
end;
begin
assign(input,'TYVJ1190.in'); reset(input);
assign(output,'TYVJ1190.out'); rewrite(output);
init;
outit;
close(input); close(output);
end.