给出一个n*m的方阵,求用1*2的多米诺骨牌恰好完全填满有多少种方案。
用f[i,s]表示第i行的状态为s的时候的方案数。s某一位为1表示已放。
f[i,s]=sum(f[i-1,ss])且满足s和ss是兼容的。下面就给出了兼容的条件。
若ss的第i位为0则s的第i位一定为1也就是要竖着放然后i+1,否则不兼容。
若ss的第i位为1且s的第i位为1则s的第i位一定要横着放,也就是仍要满足ss的i+1位和s的i+1位都是1,然后i+2;否则不兼容。
其他情况都是兼容的。
然后对于每种状态判断是否兼容后进行转移就好了。
初始状态:f[0,1 shl m-1]=1
输出f[n,1 shl m-1]。
代码:
var n,m,i,j,k:longint; f:array[0..11,0..2048] of int64; function check(x,y:longint):boolean; var i:longint; begin i:=1; while i<=m do begin if (x and 1=0)and(y and 1=0) then exit(false); if (x and 1=1)and(y and 1=0)or(x and 1=0)and(y and 1=1) then begin x:=x shr 1; y:=y shr 1; inc(i); continue; end; x:=x shr 1; y:=y shr 1; if (y and 1=0)or(x and 1=0) then exit(false); x:=x shr 1; y:=y shr 1; i:=i+2; end; check:=true; end; begin readln(n,m); while (n>0)or(m>0) do begin if n<m then begin n:=n xor m; m:=n xor m; n:=n xor m; end; if n*m mod 2=1 then begin writeln(0); readln(n,m); continue; end; fillchar(f,sizeof(f),0); f[0,1 shl m-1]:=1; for i:=1 to n do for j:=0 to 1 shl m-1 do for k:=0 to 1 shl m-1 do if f[i-1,k]>0 then if check(j,k) then f[i,j]:=f[i,j]+f[i-1,k]; writeln(f[n,1 shl m-1]); readln(n,m); end; end.