题意
题解
- dp[i][j]表示第i行第j种状态的方案数。初始化dp[0][0] = 1。
- 枚举每一行种的方案数,首先必须满足不能有相邻的1,并且种的位置都是1。
- 从上到下枚举。这一行的上一行不能有相邻的1。
代码
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <vector>
using namespace std;
int const N = 20;
int const MOD = 100000000;
int mp[N][N];
int n,m,ans;
int dp[N][1<<N]; //dp[i][j]表示第i行第j种状态下的方案数量
bool judge(int x,int state){ //10101 m = 5
if(state & (state << 1)) return false;
for(int i=1;i<=m;i++){
if(mp[x][i] == 0){ //如果这里不能种
if((1<<(m-i)) & state) return false; //但是方案里却种了
}
}
return true;
}
int main(){
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
scanf("%d",&mp[i][j]);
dp[0][0] = 1; //都没有也是一种方案
for(int i=1;i<=n;i++){
for(int j=0;j<(1<<m);j++){ //枚举状态
if(!judge(i,j)) continue;
for(int k=0;k<(1<<m);k++) //枚举上一行的状态
if(!(j&k)) dp[i][j] += dp[i-1][k]; //如果没有相邻的1
if(i == n) ans = (ans + dp[i][j]) % MOD;
}
}
printf("%d\n",ans);
return 0;
}