• 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 }
  • 相关阅读:
    strong,weak, retain, assign的区别@property的参数
    iOS 声明属性关键字讲解
    iOS中ARC和非ARC混用
    存储过程修改产品描述页图片alt描述信息
    mysql字符串函数(转载)
    读者证
    存储过程
    复制档案或目录 linux cp命令详解
    linux shell获取时间
    linux 备份日志文件
  • 原文地址:https://www.cnblogs.com/acSzz/p/2635500.html
Copyright © 2020-2023  润新知