链接:点击打开链接
题意:有一块N*M的空地,1表示可以播种,0表示不可以,现在要求播种并且播种区域不能相邻,输出所有可以播种情况的种数并对100,000,000区域
代码:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <iostream>
#include <algorithm>
using namespace std;
const long long mod=100000000;
int n,m;
int v[1<<15],d[15][15],dp[15][1<<15]; //dp[i][j]表示满足前i行的同时,第i行状态为j的情况数
int judge(int x,int y){ //判断当前状态是否满足当前行
int i;
for(i=0;i<m;i++)
if((y&(1<<i))&&!d[x][i])
return 0;
return 1;
}
int main(){
int i,j,k,u;
long long ans;
k=0;
for(i=0;i<(1<<12);i++){
if((i&(i<<1))==0)
v[k++]=i;
} //预先处理横着没有相邻的状态
while(scanf("%d%d",&n,&m)!=EOF){
for(i=0;i<n;i++)
for(j=0;j<m;j++)
scanf("%d",&d[i][j]);
memset(dp,0,sizeof(dp));
for(i=0;i<n;i++){
for(j=0;v[j]<(1<<m);j++){ //当前状态满足当前行
if(judge(i,v[j])){
if(i==0)
dp[i][j]=1; //第一行每种情况都是1
else{
for(u=0;v[u]<(1<<m);u++){ //v[u]为前一行的状态,看是否与当前行的状态v[j]矛盾
if((v[j]&v[u])==0)
dp[i][j]+=dp[i-1][u];
}
}
}
}
}
ans=0;
for(i=0;v[i]<(1<<m);i++) //最后一行所有的状态加和
ans=(ans+dp[n-1][i])%mod;
printf("%I64d\n",ans);
}
return 0;
}