玉米田327 暴风哭泣yz视频代码我没看懂
//f[i][s]表示已经种植前i行,且第i行种植的状态为s的方案数
//对于每一个合法的状态f[i][b],上一行的状态为f[i-1][a];
//f[i][b] += f[i-1][a]枚举每一个上一行能转移到下一行的状态
//(a&b) ==0
#include<bits/stdc++.h>
using namespace std;
const int N=14,M=1<<N;
const int mod=1e8;
int ma[N][N]; //用于记录土地是否肥沃
long long f[N][M]; //这道题对‘1’的数量没有限制所以我们只需要两维即可
vector<int>h[N]; //用于记录每一行的合法状态
int n,m;
int main()
{
cin>>n>>m;
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
cin>>ma[i][j];
}
/*
i是从0循环到n+1
因为我下面dp时要用到0和n+1,其实这里我们可以思考得出:对于0和n+1只有0这个状态是合法的,
因此我们也可以直接将0这个状态给0和n+1行的vector里
*/
for(int i=0;i<=n+1;i++)
{
for(int j=0;j<1<<m;j++)
{
bool jud=true;
for(int z=0;z<=m;z++)
{
if(j>>z & 1)
{
if(j>>z+1 & 1) //如果当前位是1,那么它的下一位不能是1,且当前位置土地要肥沃
{
jud=false;
break;
}
if(!ma[i][m-z])//0 表示该块土地不育
{
jud=false;
break;
}
}
}
if(jud)h[i].push_back(j);//可行合法方案放进h数组
}
}
f[0][0]=1; //土地上什么都不种也算一种方法
for(int i=1;i<=n+1;i++)
{
for(int j=0;j<h[i].size();j++) //遍历当前行合法状态
{
int a=h[i][j];
for(int z=0;z<h[i-1].size();z++) //遍历上一行合法状态
{
int b=h[i-1][z];
if((a & b)==0) //上一行和这一行同一位不能同为1.
{
f[i][a]=(f[i][a]+f[i-1][b])%mod;
}
}
}
}
cout<<f[n+1][0]<<endl;
}