SSL 1507 棋盘 状压dp

小明的爸爸给他买回一个N*M的棋盘,现在要他在上面放置骨牌,有两种骨牌可供选择:一种是1*1的,一种是1*2的,给你棋盘的大小,小明问你一共有多少种填法。

用f[i,s]表示第i行状态为s有多少种方案。然后用dfs暴力枚举状态转移就好了。

代码:

var
  n,m,i:longint;
  f:array[1..11,0..2048] of longint;

procedure work(x,y:longint);
begin
  if x>m then exit;
  if x=m then
  begin
    inc(f[1,y]);
    exit;
  end;
  work(x+1,y shl 1);
  work(x+1,y shl 1 or 1);
  work(x+2,y shl 2 or 3);
end;

procedure dfs(d,x,y:longint);
begin
  if d>m then exit;
  if d=m then
  begin
    f[i,y]:=(f[i,y]+f[i-1,x]) mod 1000;
    exit;
  end;
  dfs(d+1,x shl 1,y shl 1 or 1);
  dfs(d+1,x shl 1 or 1,y shl 1);
  dfs(d+1,x shl 1 or 1,y shl 1 or 1);
  dfs(d+2,x shl 2 or 3,y shl 2 or 3);
end;

begin
  readln(n,m);
  work(0,0);
  for i:=2 to n do
    dfs(0,0,0);
  writeln(f[n,1 shl m-1]);
end.


你可能感兴趣的:(SSL 1507 棋盘 状压dp)