n * m 个玉米
n*m个数字 0 或者1
1可以种玉米 0 不能 种玉米不能相邻
计算有几种 种的方法
#include<stdio.h> #include<algorithm> #include<string.h> using namespace std; #define MAXN 13 #define MAXN1 10000 #define mod 100000000 int n,m; int z[MAXN][MAXN]; int num[MAXN1]; int cnt; int dp[MAXN][MAXN1]; //dp[i][j] 第一维是行 第二维是列 表示这一行这个状态的数目 int x[MAXN]; //用来记录每一行的二进制数 1 void solve() // 0&1 =0 就1&1=1 { for(int i=0;i<(1<<m);i++) //所有可能的状态 就是这一行不可能相邻 10010 100100 这样可以 11010 110100 不行 if((i&(i<<1))==0) num[cnt++]=i; } bool jug(int state,int r) //这个状态 和这一行是否矛盾 { if(!(state&(~x[r]))) return 1; return 0; } int main() { while(scanf("%d%d",&n,&m)!=EOF) { for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) scanf("%d",&z[i][j]); cnt=0; solve(); memset(dp,0,sizeof(dp)); memset(x,0,sizeof(x)); for(int i=1;i<=n;i++) { for(int j=1;j<=m;j++) if(z[i][j]) x[i]+=(1<<(m-j)); } dp[0][0]=1; for(int i=1;i<=n;i++) { for(int st=0;st<cnt;st++) { if(jug(num[st],i)) //这一行 和 这个状态 { for(int pa=0;pa<cnt;pa++) { if(jug(num[pa],i-1)&&!(num[st]&num[pa]))//前一行和前一个状态 这和状态和前一个状态 dp[i][num[st]]+=dp[i-1][num[pa]]; } } } } int ans=0; for(int i=0;i<cnt;i++) //所有的数目要加一下 ans=(ans+dp[n][num[i]])%mod; printf("%d\n",ans); } return 0; }
时间: 2024-10-14 16:14:38