POJ 2411 状态压缩递,覆盖方案数

无非就是横着放与竖着放,状态中用1表示覆盖,0表示未覆盖。

 1 #include <iostream>
 2 #include <vector>
 3 #include <algorithm>
 4 #include <string>
 5 #include <string.h>
 6 #include <stdio.h>
 7 #include <queue>
 8 #include <stack>
 9 #include <map>
10 #include <set>
11 #include <cmath>
12 #include <ctime>
13 #include <cassert>
14 #include <sstream>
15 using namespace std;
16 
17 const int N=13;
18 
19 long long dp[N][1<<N];
20 
21 int h,w;
22 int row;
23 void dfs(int col,int pre,int cur) {
24     if (col>=w) {
25         dp[row][cur]+=dp[row-1][pre];
26         return;
27     }
28     if (col+1<=w) {
29         dfs(col+1,pre<<1|1,cur<<1); // 当前不放竖骨牌
30         dfs(col+1,pre<<1,cur<<1|1); // 放竖骨牌将本行与上行此列覆盖
31     }
32     if (col+2<=w) {
33         dfs(col+2,pre<<2|3,cur<<2|3); // 横放骨牌
34     }
35 }
36 int main () {
37     while (scanf("%d %d",&h,&w)!=EOF,h+w) {
38         if ((h*w)&1) {
39             puts("0");
40             continue;
41         }
42         if (h<w) swap(h,w); // 优化复杂度
43         memset(dp,0,sizeof dp);
44         dp[0][(1<<w)-1]=1;
45         for (row=1;row<=h;row++) {
46             dfs(0,0,0);
47         }
48         printf("%lld\n",dp[h][(1<<w)-1]);
49     }
50     return 0;
51 }

 

posted @ 2015-09-18 22:32  活在夢裡  阅读(223)  评论(0编辑  收藏  举报