这题的思路主要是一行一行的找,而每一行所能取到的情况用i&i<<1来找如果是0的话就成立,之后就是确定所选的情况,有没有点是不能用的,和有没有点是与上一行相连的,之后再把最后一行的所有情况加起来就好;
代码中比较难以理解的地方就是位运算的部分,比如说第一个init()函数,他的作用是找出所有满足1和1是分开放置的情况,就是说二进制表示的话起码得是101010这样,其他的见注释吧。
#include <stdio.h>
#include <cstring>
int v[1<<12],dp[13][1<<12],l;
int n,m,a[13][13];
void init()
{
int i;
l=0;
for(i=0;i<(1<<12);i++)
{
if((i&(i<<1))==0) //这个运算能找出所有若表示成二进制的形式则1和1之间是不相邻的的数
v[l++]=i;
}
}
int judge(int x,int y)
{
int i;
for(i=0;i<m;i++)
if((1<<i)&v[y]&&!a[x][i]) //先是看看该点是不是被选中了,再看该点是不是不能被选中
return 0;
return 1;
}
int main()
{
int i,j,k;
init();
while(~scanf("%d%d",&n,&m))
{
memset(dp,0,sizeof(dp));
for(i=0;i<n;i++)
for(j=0;j<m;j++)
scanf("%d",&a[i][j]);
for(i=0;i<n;i++)
{
for(j=0;v[j]<(1<<m);j++)
{
if(judge(i,j))
{
if(i==0)
dp[0][j]=1;
else
{
for(k=0;v[k]<(1<<m);k++)
if((v[k]&v[j])==0) //和上一行比较看看有没有相连的情况
dp[i][j]+=dp[i-1][k];
}
}
}
}
__int64 ans=0;
for(i=0;v[i]<(1<<m);i++)
ans=(ans+dp[n-1][i])%100000000;
printf("%d\n",ans);
}
return 0;
}