【洛谷P1879】玉米田Corn Fields

玉米田Corn Fields

题目链接

此题和互不侵犯状压DP的做法类似

f[i][j]表示前i行,第i行种植(1)/不种植(0)构成的二进制数为j时的方案数

首先我们可以预处理出所有一行中没有两个相邻的1的二进制数

然后进行暴力的DP

 1 #include<cstdio>
 2 #define mod 100000000
 3 #define N 13
 4 #define M 4100
 5 int n,m,f[N][M],a[N];
 6 int s[378],cnt,ans;
 7 inline int read(){
 8     char c=getchar();
 9     while(c!='0'&&c!='1') c=getchar();
10     return c-'0';
11 }
12 int main()
13 {
14     scanf("%d%d",&n,&m);
15     for(int i=1;i<=n;i++){
16         int x=0;
17         for(int j=m-1;j>=0;j--)
18          x+=read()*(1<<j);    //处理出该行对应的二进制数
19         a[i]=x;
20     }
21     for(int i=0;i<(1<<m);i++)
22      if((i&(i<<1))==0)     //若没有两个相邻的1
23          s[++cnt]=i;      //存在数组中
24     for(int i=1;i<=cnt;i++)  //初始化第一行边界
25      if((s[i]&a[1])==s[i])
26       f[1][s[i]]=1;
27     for(int i=2;i<=n;i++)
28      for(int j=1;j<=cnt;j++)
29       if((s[j]&a[i])==s[j])  //若s[j]中的1碰上a[i]中的0,就成了0
30        for(int k=1;k<=cnt;k++)
31         if((s[k]&s[j])==0)
32          f[i][s[j]]=(f[i][s[j]]+f[i-1][s[k]])%mod;
33     for(int i=1;i<=cnt;i++)
34      ans=(ans+f[n][s[i]])%mod;
35     printf("%d\n",ans);
36     return 0;
37 }

 

posted @ 2018-07-24 14:55  yjk  阅读(140)  评论(0编辑  收藏  举报