题意:已知有单价分别为1..6的大理石各num[1..6]块,大理石的总数不超过20000,现要将他们分成两部分,
使得两部分的总价相同,求解是否可以实现.
分析:多重背包问题.先求出总价值sum,若sum为奇数则一定不可能.否则用数组标记算法验证是否可以得到
sum div 2的价值.
code:
var f:array[0..200000] of boolean;
count:array[0..200000] of longint;
tot,sum,i,j:longint;
a:array[0..10] of longint;
begin
while not eof do
begin
inc(tot); sum:=0;
for i:=1 to 6 do
begin
read(a[i]);
inc(sum,a[i]*i);
end;
readln;
if sum=0 then halt;
writeln('Collection #',tot,':');
if sum and 1=1 then
begin
writeln('Can''t be divided.');
writeln;
continue;
end;
sum:=sum>>1;
fillchar(f,sizeof(f),false);
f[0]:=true;
for i:=1 to 6 do
begin
fillchar(count,sizeof(count),0);
for j:=i to sum do
if (not f[j])and(f[j-i])and(count[j-i]<a[i]) then
begin
f[j]:=true;
count[j]:=count[j-i]+1;
end;
if f[sum] then
begin
writeln('Can be divided.');
writeln;
break;
end;
end;
if not f[sum] then
begin
writeln('Can''t be divided.');
writeln;
end;
end;
end.