简要题意:
给出一个n*m的矩形,要求用1*2的矩形拼出来(可以旋转),问总共有多少种拼法。
题解:
将第i行进行状态压缩表示
(0,0,0,0..0) 0代表向下没有插头,1代表向下有插头
然后向下一行转移方法就是
如果当前列有插头,则取消掉插头;
如果当前列没有插头:
1、如果下一列也没有插头,可以水平放一个小矩形或者竖直放两个小矩形,插头状态不变
2、如果下一列有插头,则竖直放一个小矩形,添加两个向下的插头
注意要用
long long代码:
1 # include <iostream>
2 # include <cstring>
3 # define getbit(c,pos) (((c)&(1<<(pos)))>0)
4 using namespace std;
5 void add(int code,int now,int m,long long dp[],int num)
6 {
7 if(now==m)
8 dp[code]+=num;
9 else
10 {
11 switch(getbit(code,now))
12 {
13 case 1:
14 add(code-(1<<now),now+1,m,dp,num);
15 break;
16 case 0:
17 if(now!=m-1&&!getbit(code,now+1))
18 add(code,now+2,m,dp,num);
19 add(code+(1<<now),now+1,m,dp,num);
20 break;
21 };
22 }
23 }
24 int main()
25 {
26 int n,m;
27 while(true)
28 {
29 cin>>n>>m;
30 if(!n&&!m) break;
31 long long dp[15][2048];
32 memset(dp,0,sizeof(dp));
33 dp[0][0]=1;
34 for(int i=0;i<n;i++)
35 for(int j=0;j<(1<<m);j++)
36 if(dp[i][j])
37 add(j,0,m,dp[i+1],dp[i][j]);
38 cout<<dp[n][0]<<endl;
39 }
40 return 0;
41 }
42