这道题其实就是状压DP模板题
设 f [ i ] [ s [ j ] ] f[i][s[j]] f[i][s[j]] 表示在当前第 i i i 行的状态为 s [ i ] s[i] s[i]。
可得动态转移方程
f [ i ] [ s [ j ] ] + = f [ i − 1 ] [ s [ w ] ] ; f[i][s[j]]+=f[i-1][s[w]]; f[i][s[j]]+=f[i−1][s[w]];
注意要取模。
代码
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
using namespace std;
int a[100010],num[100010],f[12][1<<12],c[100010],flag[10010];
int n,m,k,js,ans;
bool x;
void dfs(int ans,int dep)
{
if(dep>m)
{
a[++js]=ans;
return;
}
dfs(ans,dep+1);
dfs(ans+(1<<(dep-1)),dep+2);
}
int main()
{
cin>>n>>m;
for(int i=1; i<=n; i++)
for(int j=1; j<=m; j++)
{
cin>>x;
if(x==0)
flag[i]+=1<<(j-1);
}
dfs(0,1);
for(int i=1; i<=js; i++)
if(!(a[i]&flag[1]))
f[1][a[i]]=1;
for(int i=2; i<=n; i++)
for(int j=1; j<=js; j++)
if(!(a[j]&flag[i]))
for(int w=1; w<=js; w++)
{
if(a[j]&a[w])
continue;
f[i][a[j]]=(f[i][a[j]]+f[i-1][a[w]])%100000000;
}
for(int i=1; i<=js; i++)
ans=(ans+f[n][a[i]])%100000000;
cout<<ans%100000000;
return 0;
}