sgu131 分类: sgu 2015-03-13 22:27 32人阅读 评论(0) 收藏

状态压缩 dp

f[i][t] 是指前 i1 行填满,第i行状态为 t 的方案数

full 为将一行填满的状态,可知
t^full <=> 将 t 填满的方案
t <=> 将 t^full 填满的方案

本题比较适合 DFS 逐行 dp
row 行状态为 t1,row+1 行状态为 t2
s1 列影响 s 列状态为 p1,p2

下面分7种情况讨论:
(1)当我们不在当前行当前列放 block

      0 0 
0 0
dfs(s+1,t1<<1|p1, t2<<1|p2,0 ,0);

(2)当横着放 block 时,即为:

      1 1 
0 0
dfs(s+1,t1<<1|1,t2<<1|p2,1,0); | p1 = 0

(3)当竖着放 block 时,即为:

      1 0 
1 0
dfs(s+1,t1<<1|1,t2<<1|1,0,0); | p1 = 0 & p2 = 0

(4)当 L 形如此放时,即为:

      1 0 
1 1
dfs(s+1,t1<<1|1,t2<<1|1,0,1); | p1 = 0 & p2 = 0

(5)当 L 形如此放时,即为:

      1 1 
1 0
dfs(s+1,t1<<1|1,t2<<1|1,1,0); | p1 = 0 & p2 = 0

(6)当 L 形如此放时,即为:

      0 1 
1 1
dfs(s+1,t1<<1|1,t2<<1|p2,1,1); | p2 = 0

(7)当 L 形如此放时,即为:

      1 1 
0 1
dfs(s+1,t1<<1|1,t2<<1|p2,1,1); | p1 = 0



#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<iostream>
#include<algorithm>

const int MAXN = 11;

int n,m;
long long f[MAXN][1<<MAXN] = {0};
int full , row;

void dfs(int s , int t1 , int t2 , int p1 , int p2)
{

    if(s > m)
    {
        if(!p1 && !p2)f[row+1][t2] += f[row][t1^full];  
        return ;
    } 

    dfs(s+1,t1<<1|p1, t2<<1|p2,0 ,0);

    if(!p1)
    {  
      dfs(s+1,t1<<1|1,t2<<1|p2,1,0);  
      dfs(s+1,t1<<1|1,t2<<1|p2,1,1);
    }
    if(!p2)
    {
      dfs(s+1,t1<<1|p1,t2<<1|1,1,1);    
    }
    if((!p1) && (!p2))
    {
      dfs(s+1,t1<<1|1,t2<<1|1,0,0); 
      dfs(s+1,t1<<1|1,t2<<1|1,0,1); 
      dfs(s+1,t1<<1|1,t2<<1|1,1,0); 
    }

}

int main()
{
#ifndef ONLINE_JUDGE    
   freopen("sgu131.in","r",stdin);
   freopen("sgu131.out","w",stdout);
#endif  

   std::cin >> n >> m;

   full = (1<<m) - 1;   

   f[1][0] = 1; 
   for(int i = 1 ; i <= n ; i++)
   {
      row = i;
      dfs(1 , 0 , 0 , 0 , 0);
      row = 0;
   }

   std::cout << f[n + 1][0];    

#ifndef ONLINE_JUDGE
   fclose(stdin);
   fclose(stdout); 
#endif      
   return 0;
}

版权声明:本文为博主原创文章,未经博主允许不得转载。

posted @ 2015-03-13 22:27  <Dash>  阅读(128)  评论(0编辑  收藏  举报