【蓝桥杯】拼图 CSP 201409-5 拼图问题【70分】
#状压DP#
//第i列,枚举到了第j行,当前状态是state,对下一列的影响是nex #include <cstdio> #include <cstring> #include <algorithm> #include <iostream> const int MOD=1000000007; using namespace std; int N, M; long long dp[1006][1000]; void dfs(int i,int j,int state,int nex) { if (j==M) { dp[i+1][nex]+=dp[i][state]; dp[i+1][nex] %=MOD; return; } //如果这个位置已经被上一列所占用,直接跳过 if (((1<<j)&state)>0) dfs(i,j+1,state,nex); if (((1<<j)&state)==0&&(j+1)<M&&((1<<j)&nex)==0&&((1<<(j+1))&nex)==0) /// dfs(i,j+1,state,nex|(1<<j)|(1<<(j+1))); if (j+1<M && ((1<<j)&state)==0 &&((1<<(j+1))&state)==0&& ((1<<j)&nex)==0) /// dfs(i,j+2,state,nex|(1<<j)); if (((1<<j)&state)==0&&j>=1&&(nex&(1<<j))==0&&(nex&(1<<(j-1)))==0) //_| dfs(i,j+1,state,nex|(1<<j)|(1<<(j-1))); if (j+1<M && ((1<<j)&state)==0 &&((1<<(j+1))&state)==0&& ((1<<(j+1))&nex)==0)// 7 dfs(i,j+2,state,nex|(1<<(j+1))); return; } int main() { cin>>N>>M; memset(dp,0,sizeof(dp)); dp[1][0]=1; for (int i=1;i<=N;i++) { for (int j=0;j<(1<<M);j++) if (dp[i][j]) { dfs(i,0,j,0); } } cout<<dp[N+1][0]<<endl; }