Corn Fields 玉米田
这题是状压dp的模板题。
至于状压是什么,自己上网查吧,我在这里不多说。
预处理:
1.\(f[i]\)表示第\(i\)行的玉米田可行方案;
\(ok[i]\)表示\(i\)状态是否是可行解。
判断方法:与\(i<<1\)和\(i>>1\) &后 均为0,证明脑补一下就可以了。
之后状压dp
\(dp[i][j]\) 表示枚举到第\(i\)行,状态为\(j\)的方案总数
\(dp[i][j]+=dp[i-1][k]\) 当且仅当 \(ok[i]\) 且 \(j\)&\(f[i]==j\) \(j\)&\(k==0\)
答案是 $\sum_{i=0}^{1<<m-1} dp[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) ;
}
加油ヾ(◍°∇°◍)ノ゙