先将横排压缩,在比较竖排。
#include <cstdio>
#include <cstring>
#define mod 100000000
using namespace std;
int a[20][20];
int num[20][1<<12];
int dp[20][1<<12];
int n,m;
int check(int i,int j)
{
for(int k=0; k<m; k++)
{
if((j&(1<<k))&&!a[i][k])
return 0;
if(k>0)
{
if(((j&(1<<k))&&(j&(1<<(k-1)))))
return 0;
}
}
return 1;
}
int main()
{
while(~scanf("%d%d",&n,&m))
{
for(int i=0; i<n; i++)
for(int j=0; j<m; j++)
scanf("%d",&a[i][j]);
for(int i=0; i<n; i++)
{
num[i][0]=0;
for(int j=0; j<(1<<m); j++)
{
if(check(i,j))
{
num[i][0]++;
num[i][num[i][0]]=j;
}
}
}memset(dp,0,sizeof(dp));
for(int i=1; i<=num[0][0]; i++)
dp[0][num[0][i]]=1;
for(int i=1; i<n; i++)
{
for(int j=1; j<=num[i][0]; j++)
{
for(int k=1; k<=num[i-1][0]; k++)
{
if(((num[i][j])&(num[i-1][k]))==0)
{
dp[i][num[i][j]]+=dp[i-1][num[i-1][k]];
dp[i][num[i][j]]%=mod;
}
}
}
}
/*for(int i=0;i<n;i++)
{
for(int j=0;j<(1<<m);j++)
{
printf("%d ",dp[i][j]);
}
printf("\n");
}*/
int ans=0;
for(int i=1; i<=num[n-1][0]; i++)
{
ans+=dp[n-1][num[n-1][i]];
ans%=mod;
}
printf("%d\n",ans);
}
}