题意:在权值为一的土地上种玉米,不能相邻,问有几种摆放方法。
分析:在接触过poj 2411后再来做这题应该思路就很明确了,dp[i][j]表示第i行为“J”状态时的方案数。
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
const int mod = 100000000;
const int maxn = 400;
int n,m,num;
int dp[13][maxn];
int hash[maxn];
int Map[13][13];
void init(int Max){
num=0;
for(int i=0;i<=Max;i++){
if(!((i<<1) & i)){
hash[num++]=i;
// printf("---%d\n",i);
}
}
}
bool judge(int now,int tmp){
for(int i=0;i<m;i++){
if((tmp>>i) & 1){
// puts("~~~");
if(!Map[now][m-i-1]) return false;
}
}
return true;
}
int main(){
while(~scanf("%d %d",&n,&m)){
memset(dp,0,sizeof(dp));
for(int i=0;i<n;i++){
for(int j=0;j<m;j++){
scanf("%d",&Map[i][j]);
}
}
int Max=(1<<m)-1;
init(Max);
// printf("=============%d\n",Max);
for(int i=0;i<num;i++){
int tmp=hash[i];
if(judge(0,tmp)){
// printf("%d\n",tmp);
dp[0][i]=1;
}
}
for(int i=1;i<n;i++){
// printf("");
for(int j=0;j<num;j++){
int tmp_j=hash[j];
// printf("%d========",hash[j]);
if(!judge(i,tmp_j)) continue;
for(int k=0;k<num;k++){
//printf("--\n");
int tmp_k=hash[k];
if(!judge(i-1,tmp_k)) continue;
if(tmp_k & tmp_j) continue;
// printf("tmp_j======%d----------%d -- %d ====\n",tmp_j,tmp_k,k);
dp[i][j]+=dp[i-1][k];
// printf("%d=-\n",dp[i-1][k]);
//printf(" %d-----%d\n",hash[j],hash[k]);
dp[i][j]%=mod;
}
}
}
int ans=0;
for(int i=0;i<num;i++){
// printf("%d-----%d-----%d\n",i,hash[i],dp[n-1][i]);
ans+=dp[n-1][i];
ans%=mod;
}
printf("%d\n",ans);
}
}