正题
评测记录:https://www.luogu.org/recordnew/lists?uid=52918&pid=P1879
大意
有n*m的矩阵,有些地方可以放,有些不可以放,不可以相邻的放,求放置方法总数。
解题思路
先用二进制表示每一行的是否可以放置的状态。
然后用state[i]state[i]来表示只计算单行第ii种状态是否合法。
然后每次将状态左移和右移一位然后用&运算判断是否合法就行了。
之后我们开始dp
用表示第i行第j种状态的方案数。然后我们枚举上一行的状态kk<script type="math/tex" id="MathJax-Element-2449">k</script>,然后判断两个状态是否合法。
code
#include<cstdio>
#include<algorithm>
#define MN 4100
using namespace std;
int n,m,c,f[MN],F[14][MN],state[MN],ans,MS;
int main()
{//freopen("cowfood.in","r",stdin);//freopen("cowfood.out","w",stdout);scanf("%d%d",&n,&m);for (int i=1;i<=n;i++)for (int j=1;j<=m;j++){ scanf("%d",&c);f[i]=(f[i]<<1)+c;}MS=1<<m;for (int i=0;i<MS;i++)state[i]=!(i&(i<<1)||i&(i>>1));F[0][0]=1;for (int i=1;i<=n;i++)for (int j=0;j<MS;j++)if (state[j]&&(j&f[i])==j)for (int k=0;k<MS;k++)if (!(k&j))F[i][j]=(F[i][j]+F[i-1][k])%100000000;for (int i=0;i<MS;i++)ans=(ans+F[n][i])%100000000;printf("%d",ans);
}