题意很简单,用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.