题目链接
这是一道让你在nm的矩形中用12的长方形填满的方法种类数
首先如果长方形横着摆放那么在横向上就要占据两个位置且用1,1表示状态。如果是竖着摆放,那么这个位置用0表示的话,那么就表示是与下面一行竖着摆放的,且下面的这个位置用1表示;如果这个位置用1表示的话,那么表示是与上面一行竖着摆放的,且上面的那个位置用0表示。
#include<stdio.h>
#include<string.h>
#include<iostream>
#include<algorithm>
using namespace std;
typedef long long ll;
ll n,m,dp[20][1<<12];//dp[x][y],x表示第几行,y表示长方形摆放的形式,用二进制来表示如1100110,0011000等等。
void dfs(int x,int sta)//初始化第一行的摆放种类数
{
if(x==m)
{
dp[1][sta]=1;
return ;
}
if(x+1<=m)
dfs(x+1,sta<<1);//竖着摆放,占据一个位置,用0表示
if(x+2<=m)
dfs(x+2,sta<<2|3);//横向摆放,占据两个位置用1,1表示
}
void dfs1(int i,int now,int pre,int x)//now表示当前一行摆放的形式,pre表示上一行摆放的形式。
{
if(x==m)
{
dp[i][now]+=dp[i-1][pre];
return ;
}
if(x+1<=m)
{
dfs1(i,now<<1|1,pre<<1,x+1);//竖着摆放1,0的形式。
dfs1(i,now<<1,pre<<1|1,x+1);//竖着摆放0,1的形式。
}
if(x+2<=m)
dfs1(i,now<<2|3,pre<<2|3,x+2);//横着摆放
}
int main()
{
while(scanf("%lld %lld",&n,&m)!=EOF,n+m)
{
memset(dp,0,sizeof(dp));
if((n*m)%2==1)//因为由面积的关系可以得到,若长方形铺满矩形的话,面积一定为偶数。
{
printf("0\n");
continue;
}
dfs(0,0);
int i;
for(i=2;i<=n;i++)//层层进行遍历。
dfs1(i,0,0,0);
printf("%lld\n",dp[n][(1<<m)-1]);
}
return 0;
}