传送门
http://poj.org/problem?id=2411
题目大意
1*2骨牌,覆盖n*m棋盘的方式总数
题解
http://blog.csdn.net/xiaozhuaixifu/article/details/10221341这篇比较清楚
var
dp:array[0..200,0..3000]of int64;
i,j,k:longint;
n,m:longint;
function check1(a:longint):longint;
var i:longint;
begin
i:=1;
while i<=m do
begin
if a and (1<<(i-1))=0
then inc(i)
else
if (a and (1<<i)<>0)and(i<=m-1)
then inc(i,2)
else exit(0);
end;
exit(1);
end;
function check(a,b:longint):longint;
var i,j,k:longint;
begin
i:=1;
while i<=m do
begin
if a and (1<<(i-1))=0
then begin
if b and (1<<(i-1))=0
then exit(0)
else inc(i);
end
else begin
if b and (1<<(i-1))=0
then inc(i)
else
if (i<=m-1)and(a and (1<<i)<>0)and(b and (1<<i)<>0)
then inc(i,2)
else exit(0);
end;
end;
exit(1);
end;
begin
while not eof do begin
readln(n,m); if (n=0)and(m=0) then break;
if n<m then begin k:=n; n:=m; m:=k; end;
fillchar(dp,sizeof(dp),0);
for j:=0 to (1<<m)-1 do
if check1(j)=1
then dp[1,j]:=1;
for i:=2 to n do
for j:=0 to (1<<m)-1 do
for k:=0 to (1<<m)-1 do
if check(j,k)=1
then dp[i,j]:=dp[i,j]+dp[i-1,k];
writeln(dp[n,(1<<m)-1]); end;
end.