标签:
题目大意:一个宽w高为h的棋盘,现在要用1*2的多米诺骨牌不重叠地覆盖整个棋盘,问有多少种方案。
h<11,w<11
分析:1.h*w若为奇数,则无解。
2.按行处理。处理第i行时,保证前i-1行全部覆盖,当前行的状态为state。
以f[i][state]表示处理到第i行,第i行的状态为state,且前i-1行全部填满的方案数。
f[i][state]=∑f[i-1][state2]
需要统计有哪些state2可以转移到state。这个可以用dfs来预处理出来。
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<vector> 5 #include<cstring> 6 using namespace std; 7 #define MAXN 2200 8 vector<int> arr[MAXN]; 9 long long f[2][MAXN],h,w,n,ss; 10 int tt; 11 void find(int s,int t,int i) 12 { 13 if(s==0||i>=n){arr[ss].push_back(t);return;} 14 if(s&1) 15 { 16 if(s&2) 17 find(s>>2,t,i+2); 18 find(s>>1,t^(1<<i),i+1); 19 } 20 else 21 find(s>>1,t,i+1); 22 } 23 int main() 24 { 25 n=11; 26 int z=(1<<n)-1; 27 for(int i=0;i<=z;i++) 28 { 29 ss=i; 30 find(i,z,0); 31 } 32 while(scanf("%d%d",&h,&w)&&(w||h)) 33 { 34 memset(f,0,sizeof f); 35 if(w%2&&h%2) 36 {printf("0\n"); 37 continue; 38 } 39 int z1=(1<<w)-1; 40 f[0][z1]=1; 41 for(int i=1;i<=h;i++) 42 { 43 for(int j=0;j<=z1;j++) 44 { 45 f[i&1][j]=0; 46 for(int k=0;k<arr[j].size();k++) 47 { 48 f[i&1][j]+=f[!(i&1)][arr[j][k]&z1]; 49 } 50 } 51 } 52 printf("%I64d\n",f[h&1][z1]); 53 } 54 }
标签:
原文地址:http://www.cnblogs.com/hefenghhhh/p/4609927.html