这题是状压dp的模板题。
至于状压是什么,自己上网查吧,我在这里不多说。
预处理:
1. f[i] f [ i ] 表示第 i i 行的玉米田可行方案;
表示 i i 状态是否是可行解。
判断方法:与和 i>>1 i >> 1 &后 均为0,证明脑补一下就可以了。
之后状压dp
dp[i][j] d p [ i ] [ j ] 表示枚举到第 i i 行,状态为的方案总数
dp[i][j]+=dp[i−1][k] d p [ i ] [ j ] + = d p [ i − 1 ] [ k ] 当且仅当 ok[i] o k [ i ] 且 j j & j j &
答案是 ∑1<<m−1i=0dp[n][i] ∑ i = 0 1 << m − 1 d p [ n ] [ i ]
注意取模
#include <cstdio>
using namespace std ;
const int p = 100000000 ;
int dp[13][5000],a[13][13],f[13],ok[5000];
int n,m ;
int main(){
scanf("%d%d",&n,&m) ;
for (int i=1;i<=n;i++)
for (int j=1;j<=m;j++)
scanf("%d",&a[i][j]) ;
for (int i=1;i<=n;i++)
for (int j=1;j<=m;j++)
f[i]=(f[i]<<1)+a[i][j] ;
for (int i=0;i<(1<<m);i++) ok[i]=((!(i&(i<<1)))&&(!(i&(i>>1)))) ;
dp[0][0]=1 ;
for (int i=1;i<=n;i++)
for (int j=0;j<(1<<m);j++)
if (ok[j] && ((j&f[i])==j)){
for (int k=0;k<(1<<m);k++) if (!(j&k)) dp[i][j]=(dp[i][j]+dp[i-1][k])%p ;
}
int ans=0;
for (int i=0;i<(1<<m);i++) ans=(ans+dp[n][i])%p ;
printf("%d\n",ans) ;
}