I and OI
Past...

题意:已知有单价分别为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.

posted on 2011-08-10 12:16  exponent  阅读(263)  评论(0编辑  收藏  举报