无非就是横着放与竖着放,状态中用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 ",dp[h][(1<<w)-1]); 49 } 50 return 0; 51 }