状压动规_(POJ2411)

题意很简单,用1*2的小矩形不重叠也不漏地铺满n*m的矩形,问方案数.

解法自然是状态压缩DP.

考虑每一行,用一个二进制串表示其状态,若第i位为1则表示在这一行的第i列竖放一个矩形,

它占用了这一行和下一行的第i列(下一行的第i列为0).其余的0表示横放的矩形.

具体做法:用f[i,j]表示第i行放置方法为j(j是二进制数)的方案数.

显然第一行的二进制串中不能出现连续的奇数个.

对于第i行的二进制串now,第i-1行的二进制串pre,它们应该满足now and pre=0,

且now or pre中也不能含连续奇数个0.

对于最后一行,只要上一行的二进制串中不含连续奇数个0即可.

code:

var   p:array[1..11,0..2500] of longint;
      f:array[1..11,0..2500] of int64;
      n,m:longint;

      function check(num,mm:longint):boolean;
      var   sum:longint;
      begin
            sum:=0;
            num:=num+1<0 do
            begin
                  if num and 1=0 then inc(sum)
                  else if sum and 1=1 then exit(false)
                       else sum:=0;
                  num:=num>>1;
            end;
            if sum and 1=1 then exit(false)
            else exit(true);
      end;

      procedure prepare;
      var   O:longint;
      begin
            for M:=1 to 11 do
               for O:=0 to 1<0 then
                 for k:=0 to 1<0 then
                 if check(j,m) then
                 ans:=int64(ans)+int64(f[n-1,j]);
            exit(ans);
      end;

begin
      prepare;
      while not eof do
      begin
            readln(n,m);
            if n+m=0 then halt;
            if ((n and m) and 1)=1 then
              begin writeln(0); continue; end
            else if n=1 then
                   begin writeln(1); continue; end
                 else writeln(DP(n,m));
      end;
end.


 

类似的题目还有POJ1185,POJ3254.

转载于:https://www.cnblogs.com/exponent/archive/2011/08/07/2130135.html

你可能感兴趣的:(状压动规_(POJ2411))