Expert as he was in this material, he saw at a glance that he'll need a computer to calculate the number of ways to fill the large rectangle whose dimensions were integer values, as well. Help him, so that his dream won't turn into a nightmare!
Input
The input contains several test cases. Each test case is made up of two integer numbers: the height h and the width w of the large rectangle. Input is terminated by h=w=0. Otherwise, 1<=h,w<=11.Output
For each test case, output the number of different ways the given rectangle can be filled with small rectangles of size 2 times 1. Assume the given large rectangle is oriented, i.e. count symmetrical tilings multiple times.Sample Input
1 2
1 3
1 4
2 2
2 3
2 4
2 11
4 11
0 0
Sample Output
1
0
1
2
3
5
144
51205
题意:求一个h*w的正方形分割成若干个1*2的小正方形 有多少种方案。
思路:对于任意一种方案,考虑以行为界限,dp[i][j]表示前i行 当前行状态为二进制j(1表示竖着放的正方形的上半部分,0表示其他情况)的方案数
dp[i][j]+=dp[i-1][k]
当且仅当 j&k==0 : 当k为1时 保证对应j的0。 j|k 0的个数必须为偶数
#include<cstdio> #include<cstring> #include<algorithm> #include<iostream> #include<string> #include<vector> #include<stack> #include<bitset> #include<cstdlib> #include<cmath> #include<set> #include<list> #include<deque> #include<map> #include<queue> #define ll long long int using namespace std; inline ll gcd(ll a,ll b){return b?gcd(b,a%b):a;} inline ll lcm(ll a,ll b){return a/gcd(a,b)*b;} int moth[13]={0,31,28,31,30,31,30,31,31,30,31,30,31}; int dir[4][2]={1,0 ,0,1 ,-1,0 ,0,-1}; int dirs[8][2]={1,0 ,0,1 ,-1,0 ,0,-1, -1,-1 ,-1,1 ,1,-1 ,1,1}; const int inf=0x3f3f3f3f; const ll mod=1e9+7; ll dp[15][1<<11]; //前i行 状态为j的方案数 int isodd[1<<11]; //判断是否有偶数个0 void init(int m){ //预处理 for(int i=0;i<(1<<m);i++){ int cnt=0; int f=1; for(int j=0;j<m;j++){ if((i>>j)&1){ if(cnt&1) f=0; cnt=0; }else ++cnt; } if(cnt&1) f=0; isodd[i]=f; } } int main(){ ios::sync_with_stdio(false); int w,h; while(cin>>h>>w){ if(w==0&&h==0) break; memset(dp,0,sizeof(dp)); init(w); dp[0][0]=1; for(int i=1;i<=h;i++){ for(int j=0;j<(1<<w);j++){ for(int k=0;k<(1<<w);k++) if((j&k)==0&&isodd[j|k]) dp[i][j]+=dp[i-1][k]; } } cout<<dp[h][0]<<endl; } return 0; }