poj 3254 Corn Fields (状态 dp)

题意:一个row*col的矩阵,每个格子是0或者1,1表示土壤肥沃可以种植草地,0则不可以。在种草地的格子可以放牛,但边相邻的两个格子不允许同时放牛,问总共有多少种放牛的方法?(不放牛也算一种情况)

 http://poj.org/problem?id=3254


/*
折腾了 半个下午 和一个晚上 ,终于 把这道 状态dp 的题给 A 了,兴奋一下。。。。
前后想了 三个状态方程,前两个 被 k 掉了

我的一个错的 状态方程是
  dp[r] = (第 r 行 合适的状态 个数) * dp[r - 1];
  dp[r] 表示 从 第 0行 到 第 r 行的最大值
  这个 最后 验证是错的 ,忽略了 r-1 行 和 r 行 不 匹配的情况
 
 
 
  正确的 状态转移方程式 :(和 错的 就差那么一点)
   dp[r][i] = 求和 dp[r - 1][j]  ; 表示 第 r 行为 i 状态时 的最大值  它 == r-1 行所有合适的 状态 j 的 和 ;
    
*/
 1 #include<stdio.h>
 2 #include<iostream>
 3 #include<algorithm>
 4 #include<cstring>
 5 #include<cmath>
 6 #include<queue>
 7 #include<set>
 8 #include<map>
 9 #define Min(a,b)  a>b?b:a
10 #define Max(a,b)  a>b?a:b
11 #define CL(a,num)  memset(a,num,sizeof(a));
12 #define inf 9999999
13 #define maxn 400
14 #define mod 100000000
15 #define eps  1e-6
16 #define ll long long
17 using namespace std;
18 ll dp[15][400];
19 int stat[400],cnt ,mat[15];
20 bool ok(int x)
21 {
22     if(x & (x<<1)) return false ;
23 
24     return true ;
25 }
26 void find(int x)
27 {
28     for(int  i = 0 ; i < (1 << x);++i)
29     {
30         if(ok(i))
31         {
32             stat[cnt++] = i;
33         }
34     }
35 }
36 int main()
37 {
38     int  n,m,i,j,a;
39     while(scanf("%d%d",&n,&m)!=EOF)
40     {
41         cnt = 0 ;
42         CL(mat, 0);
43            for( i = 0 ; i < n ; ++i)
44            {
45                for( j  = 0;j < m ;++j)
46                {
47                    scanf("%d",&a);
48                    if(a == 0) mat[i]|= (1 << j);
49                }
50            }
51 
52            find(m);
53         
54            CL(dp,0);
55            for( i = 0 ; i < cnt; ++i)//第 0 行 特殊 处理
56            {
57                if(!(stat[i]&mat[0]))
58                {
59 
60                    dp[0][i]++;
61                }
62            }
63 
64 
65 
66            int r,f;
67            for( r = 1; r < n ; ++r)
68            {
69 
70                for(i = 0; i < cnt; ++i)
71                {
72 
73                     if(stat[i]&mat[r])continue ;
74 
75                     for(j = 0 ; j < cnt; ++j)
76                     {
77                         if(stat[j]&mat[r - 1])continue ;
78                         if((stat[i]&stat[j]))continue ;
79                         dp[r][i] += dp[r - 1][j] ;  
80 
81                     }
82 
83 
84 
85                }
86            }
87 
88              ll ans = 0;
89              for( i = 0 ; i < cnt ; ++i)
90              {
91                  if(stat[i]&mat[n - 1])continue ;
92                  ans += dp[n - 1][i];
93                  ans %= mod;
94              }
95            printf("%lld\n",ans%mod);
96 
97 
98     }
99 }
原文地址:https://www.cnblogs.com/acSzz/p/2635500.html