【蓝桥杯】拼图 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;

}

 

posted @ 2020-05-10 16:11  清谗  阅读(265)  评论(0编辑  收藏  举报