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 }

 

 

 

你可能感兴趣的:(Field)