1*2骨牌铺满n*m的方格
状态压缩
1.DFS
2.枚举判断
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
using namespace std;
int n,m,p,S;
int dp[10010][32];//i-1行状态为s
int f[32][32];//从状态s1->s2
void DFS(int num,int s1,int s2){
if(num==m){
f[s1][s2]++;
return;
}
DFS(num+1,s1<<1,s2<<1);
DFS(num+1,s1<<1|1,s2<<1|1);
if(num+2<=m)
DFS(num+2,(s1<<2)+3,s2<<2);
}
int main(){
freopen("domino.in","r",stdin);
freopen("domino.out","w",stdout);
scanf("%d%d%d",&n,&m,&p);
S=(1<<m)-1;
DFS(0,0,0);
DFS2(0,0);
dp[0][S]=1;
//The first line is gone
for(int i=1;i<=n+1;i++)
for(int j=0;j<=S;j++)
for(int l=0;l<=S;l++)
dp[i][l]=(dp[i][l]+dp[i-1][j]*f[S^j][l])%p;
printf("%d",dp[n+1][0]%p);
return 0;
}