状态压缩DP,注意不能选的地方和不挨着对本行一个意思,本行自己选的是另一个意思。可相邻与范围限制不同。
#include<algorithm>
#include<iostream>
#include<iterator>
#include<cstdlib>
#include<cstring>
#include<cstdio>
#include<map>
#define inf (1<<30)
#define MOD 100000000
using namespace std;
typedef long long ll;
const int maxn=10+100;
ll dp[2][1<<14];
int vis[1<<14];
ll add;
int in[14];
int N,M;
int cp;
void dfs(int r,int c,int cur)
{
if(cur==M)
{dp[r][c]=(dp[r][c]+add)%MOD;return;}
dfs(r,c,cur+1);
if(cur<=M-1 && !((1<<cur)&c))
{
if(((1<<cur)&cp)) return;
if(cur==0)
{
if(!((1<<cur+1)&c))
dfs(r,c| (1<<cur),cur+1);
}
else if(cur==M-1)
{
if(!((1<<cur-1)&c))
dfs(r,c|(1<<cur),cur+1);
}
else if(!((1<<cur+1)&c) && !((1<<cur-1)&c))
dfs(r,c | (1<<cur) ,cur+2);
}
}//处理好自己的位置就行,之前用while错了
int main()
{
while(~scanf("%d%d",&N,&M))
{
int rt=(1<<M)-1;
for(int i=0;i<N;i++)
{
int t=0,k;
for(int j=0;j<M;j++)
{
scanf("%d",&k);
k=1-k;
if(k)
t|=1<<j;
}
in[i]=t;
}
memset(dp,0,sizeof(dp));
add=1;cp=in[0];
dfs(0,0,0);
for(int i=1;i<N;i++)
{
memset(dp[i%2],0,sizeof(dp[0]));
for(int j=0;j<=rt;j++)if(dp[(i-1)%2][j])
{
add=dp[(i-1)%2][j];
cp=j|in[i];
dfs(i%2,0,0);
}
}
ll ans=0;
for(int j=0;j<=rt;j++)
ans+=dp[(N-1)%2][j],ans%=MOD;
printf("%I64d\n",ans);
}
return 0;
}