状态压缩dp/sgu 131 Hardwood floor

题意

  给出一个n*m的格子,要求用1*2的块和2*2缺一角的块填满,求方案数

分析

  状压dp,以下来自nocow:

  状态压缩DP,转移的时候情况很多,要一个个写出来理清楚再写。 一行一行推,opt1为上一行的状态,opt2为当前行的状态,u1,u2分别为上下两行是否与左边相连而凸出来。

/*
  Case   1    2    3    4            5            6             7
            |    +-   |    L  or U    L| or U|   -+ or -+   L or U or L or U
            |    |    +-   --    --   -+    -+     W|    L|   W    W    L    L

     old    L     : connect with Left block
             U     : connect with Upper block
     new    - | + : describe the shape of forms
     empty  W     : NO put this block, wait for the forms of next row
*/

 

Accepted Code

 1 /*
 2   PROBLEM:sgu131
 3   AUTHER:Rinyo
 4   MEMO:状态压缩dp 
 5 */
 6 
 7 #include<cstdio>
 8 long long f[10][512];
 9 int n,m,i;
10 
11 void dfs(int j,int s1,int s2,int u1,int u2)
12 {
13      if (j==m)
14      {
15               if (u1==0 && u2==0) f[i+1][s2]+=f[i][s1];
16               return;
17      }
18      if (u2==0)
19      {
20                if (u1==0)
21                {
22                          dfs(j+1,s1<<1,(s2<<1)+1,0,0);
23                          dfs(j+1,s1<<1,(s2<<1)+1,1,0);
24                          dfs(j+1,s1<<1,(s2<<1)+1,0,1); 
25                }
26                dfs(j+1,(s1<<1)+1-u1,(s2<<1)+1,0,1);
27                dfs(j+1,(s1<<1)+1-u1,(s2<<1)+1,1,1);
28      }
29      if (u1==0) dfs(j+1,(s1<<1),(s2<<1)+u2,1,1);
30      dfs(j+1,(s1<<1)+1-u1,(s2<<1)+u2,0,0);
31 } 
32 
33 
34 int main()
35 {
36     scanf("%d%d",&n,&m);
37     if (n<m) {int t=n;n=m;m=t;}
38     f[0][(1<<m)-1]=1;
39     for (i=0;i<n;i++) dfs(0,0,0,0,0);
40     printf("%I64d",f[n][(1<<m)-1]);
41     return 0;
42 }

 

posted @ 2013-03-24 09:55  Rinyo  阅读(711)  评论(0编辑  收藏  举报