状态压缩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 }

 

你可能感兴趣的:(OO)