Description
给出 n * m (1≤n、m≤10)的方格棋盘
用 1 * 2 的矩形的骨牌和 L 形的(2 * 2 的去掉一个角)骨牌不重叠地覆盖,求覆盖满的方案数。
Format
Input
一行给出N,M
Output
如题
Samples
输入数据 1
2 3
Copy
输出数据 1
5
代码!
#include<bits/stdc++.h>
using namespace std;
long long nt,k,p,n,m,sa,f[120][2002944],sss,ss;
bool ch(int st,int p){
return !((st>>p)&1);
}
void dfs(int sa,int nt,int p,int k,long long v){
//f[k][nt]+=v;
if(p==n){
f[k][nt]+=v;
return ;
}
if(sa&(1<<p)){
dfs(sa,nt,p+1,k,v);
}
else{
if(ch(nt,p)){
dfs(sa|(1<<p),nt|(1<<p),p+1,k,v);
int st=sa|(1<<p);
if(p+1<n&&ch(sa,p+1)){
dfs(st|(1<<(1+p)),nt|(1<<p),p+1,k,v);
}
st=nt|(1<<p);
if(p+1<n&&ch(nt,p+1)){
dfs(sa|(1<<p),st|(1<<(1+p)),p+1,k,v);
}
if(p-1>=0&&ch(nt,p-1)){
dfs(sa|(1<<p),st|(1<<(p-1)),p+1,k,v);
}
}
if(p+1<n&&ch(sa,p+1)){
int st=sa|(1<<p);
dfs(st|(1<<(p+1)),nt,p+1,k,v);
if(ch(nt,p+1)){
dfs(st|(1<<(p+1)),nt|(1<<(p+1)),p+1,k,v);
}
}
}
}
int main(){
scanf("%lld%lld",&m,&n);
int tt=1<<n;
//memset(f,0,sizeof(f));
f[1][0]=1;
for(int i=1;i<=m;i++){
for(int j=0;j<tt;j++){
if(f[i][j]){
dfs(j,sss,ss,i+1,f[i][j]);
}
}
}
long long an=f[m+1][0];
cout<<an;
}