大致题意:有一块地,然后,不对,这是中文题,不用说题意,还是说一下,不然这篇博客看起来就像是划水的博客一样,就是选则一些为1的区域去种草,不能在相邻的区域种草,问种草的方案有多少种。很明显的状压DP,首先预处理出每一行中 可以种草的情况,就是处理出那些草不相邻的并且没有在0上种草的合法情况。然后再对每一行的合法情况:去加上前一行的合法情况的种类,当然,要判断能否从前一行转移到当前行。
最后,代码:
#include<bits/stdc++.h>
using namespace std;
int arr[15][15];
int dp[15][1<<14];
const int mod=1e9;
int F[15];
int main()
{
int n,m;
cin>>n>>m;
for(int i=0;i<n;++i)
{
int temp=0;
for(int j=0;j<m;++j)
{
cin>>arr[i][j];
if(arr[i][j]==0)
temp=temp+(1<<(m-j-1));
}
F[i]=temp;
}
for(int i=0;i<n;++i)
{
for(int j=0;j<(1<<m);++j)
{
bool flag=true;
if((j&(j<<1))||(j&(j>>1)))
flag=false;
for(int k=0;k<m;++k)
{
if(j&F[i])
flag=false;
}
if(flag)
dp[i][j]=1;
}
}
for(int i=1;i<n;++i)
{
for(int j=0;j<(1<<m);++j)
{
if(dp[i][j])
{
dp[i][j]=0;
for(int k=0;k<(1<<m);++k)
{
if(!(j&k))
dp[i][j]=(dp[i][j]+dp[i-1][k])%mod;
}
}
}
}
int ans=0;
for(int i=0;i<(1<<m);++i)
{
ans=(ans+dp[n-1][i])%mod;
}
cout<<ans<<endl;
return 0;
}