分析:
限制条件:由于不能有公共边缘,并且只有在肥沃的土地上才可以种植,那么必须满足下面三种限制条件
- 只能在肥沃的土地上种 不能 x>>i&1 && a[i][line]==0
- 同一列 不能连续种植 不能 x>>i&1 x>>i+1&1
- 同一行 不能连续种植 a&b==0
初始化:0
边界:dp[0][0]=1
比较直观的is_valid()方法
#include <iostream>
#include <algorithm>
#include <cstring>
#include <vector>
using namespace std;
const int N=13,M=1<<N;
const int mod=1e8;
int n,m;
int a[N][N];
int dp[N][M];
vector<int> state;
bool check(int x)
{
for(int i=0;i<n;i++)
if((x>>i&1)&&(x>>(i+1)&1)) return false;
return true;
}
bool is_valid(int x,int line)
{
for(int i=0;i<n;i++)
if(x>>i&1 && a[i][line]==0)
return false;
return true;
}
int main()
{
cin>>n>>m;
for(int i=0;i<n;i++)
for(int j=1;j<=m;j++)
cin>>a[i][j];
for(int i=0;i<1<<n;i++)
if(check(i))
state.push_back(i);
dp[0][0]=1;
for(int i=1;i<=m+1;i++)
for(int j=0;j<state.size();j++)
for(int k=0;k<state.size();k++)
{
int a=state[j],b=state[k];
if(is_valid(a,i)&&(a&b)==0)
dp[i][a]=(dp[i][a]+dp[i-1][b])%mod;
}
cout<<dp[m+1][0]<<endl;
return 0;
}
二进制存储土地状态的方法
#include <iostream>
#include <algorithm>
#include <cstring>
#include <vector>
using namespace std;
const int N=14,M=1<<N;
const int mod=1e8;
int n,m;
int g[M];
int dp[N][M];
vector<int> state;
bool check(int x)
{
for(int i=0;i<m;i++)
if((x>>i&1)&&(x>>(i+1)&1)) return false;
return true;
}
int main()
{
cin>>n>>m;
for(int i=1;i<=n;i++)
for(int j=0;j<m;j++)
{
int a;
cin>>a;
g[i]+=(a==0)?1<<j:0;
}
for(int i=0;i<1<<m;i++)
if(check(i))
state.push_back(i);
dp[0][0]=1;
for(int i=1;i<=n+1;i++)
for(int j=0;j<state.size();j++)
for(int k=0;k<state.size();k++)
{
int a=state[j],b=state[k];
if((a&b)==0&&(g[i]&a)==0)
dp[i][a]=(dp[i][a]+dp[i-1][b])%mod;
}
cout<<dp[n+1][0];
return 0;
}