poj3254 Corn Fields
【题意】
输入一个m*n的矩阵可以放牛,其中有一些地方不能放牛,放牛的规则是牛与牛
之间只要不相邻就可以,可以不放,问有多少种方案。1 ≤ M ≤ 12; 1 ≤N ≤ 12
。输出结果要对1e8取余。
【分析】
基础的状压dp问题,f[i][j]表示第i行状态为j的方案数
我们可以枚举每一行的可行状态和上一行的状态,如果没有挨着的情况,那么就可以直接进行更新答案
【代码】
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> using namespace std; typedef long long ll; const int mod=1e8; int n,m; int able[5005],tot; bool check(int x) { if(x&(x<<1)) return false; return true; } void init() { for(int i=0;i<(1<<m);i++) if(check(i)) able[++tot]=i; } int field[13],f[13][5005]; int main() { scanf("%d%d",&n,&m); int x; init(); for(int i=1;i<=n;i++) { int state=0; for(int i=1;i<=m;i++) { scanf("%d",&x); x=(!x); state=(state<<1)+x; } field[i]=state; } for(int i=1;i<=tot;i++) { if(able[i]&field[1]) continue; f[1][i]=1; } for(int i=2;i<=n;i++) { for(int j=1;j<=tot;j++) { int st=able[j]; if(st&field[i]) continue; for(int k=1;k<=tot;k++) { if(st&able[k]) continue; f[i][j]=(f[i][j]+f[i-1][k])%mod; } } } int ans=0; for(int i=1;i<=tot;i++) ans=(ans+f[n][i])%mod; printf("%d\n",ans); return 0; }