zoukankan      html  css  js  c++  java
  • HDU 5965(三行扫雷 dp)

    题意是在一个 3 行 n 列的图上进行扫雷,中间一行没有雷,且中间一行的每一格都会显示周围的雷数,问根据已知的雷数在上下两行设置地雷的方法数。

    分析知每一列所填雷数的和与周围的雷数有关,但每列具体的填法只影响方法数,不影响周围的雷数统计,而且每列的雷数只有 0,1,2 这三种,

    用数组 dp[ ] 来记录每列的雷数,用数组 a[ ] 来记录所给的信息( 每一列出现的周围雷数的统计 ),则:

    dp[ pos ] = a[ pos - 1 ] - dp[ pos - 1 ] - dp[ pos - 2 ];

    dp[ 0 ] = 0 

    令 dp[ 1 ] = 0,用转移方程得到数组 dp[ ] 之后,对于每一列雷数和为 0 或 2 的情况,该列都只有一种填法,而对于每一列雷数和为 1 的情况,该列有两种填法,

    用乘法原理可知:当 dp[ 1 ] = 0 时,ans =  pow(2, 单列雷数和为 1 的列数);

    同理,再求出当 dp[ 1 ] = 1 和 dp[ 1 ] = 2 的 ans,答案即为三个 ans 的和,但要注意若在求解 dp[ ] 的过程中出现所填雷数已超过规定雷数的情况或者要填多于 2 的

    雷数,则该情况下的 ans不能被求和 (事实上也无法正确求出 ans )

    分析样例:22

    i 的值分别取 0,1,2,则 dp[ 1 ] = {0,1,2},dp[ 2 ] 则分别填 2,1,0,

    那么答案就是 sum = 1( dp[ 1 ] = 0, dp[ 2 ] = 2 ) + 4 ( dp[ 1 ] = 1, dp[ 2 ] = 1 ) + 1( dp[ 1 ] = 2, dp[ 2 ] = 0 ) = 6 

    代码如下:

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 const int mod = 1e8+7;
     4 int main()
     5 {
     6     std::ios::sync_with_stdio(false);
     7     int t,len,pos,f,a[10005],dp[10005];
     8     long long ans,sum;
     9     string s;
    10     cin >>t;
    11     while(t--)
    12     {
    13         cin >> s;
    14         len = s.length();
    15         for(int i = 0; i < len; ++i)
    16             a[i+1] = s[i] - '0';
    17         sum = 0;
    18         for(int i = 0; i <= a[1] && i <= 2; ++i)
    19         {
    20             ans = 1;
    21             f = 1;
    22             dp[0] = 0;
    23             dp[1] = i;
    24             for(pos = 2; pos <= len; ++pos)
    25             {
    26                 dp[pos] = a[pos-1] - dp[pos-1] - dp[pos-2];
    27                 if(dp[pos]<0||dp[pos]>2)
    28                 {
    29                     f = 0;
    30                     break;
    31                 }
    32             }
    33             if(pos==len+1 && dp[len]+dp[len-1]!=a[len])
    34                 f = 0;
    35             if(f)
    36             {
    37                 for(int j = 1; j <= len; ++j)
    38                     if(dp[j]==1) ans=ans*2%mod;
    39                 sum = (ans+sum)%mod;
    40             }
    41         }
    42         cout << sum << endl;
    43     }
    44     return 0;
    45 }
    View Code

    感谢这些博客的作者:

    与本题题解相关:

    https://blog.csdn.net/elbadaernu/article/details/54773033

    https://www.cnblogs.com/heimao5027/p/6033812.html

    关于手动扩大栈内存(第二篇题解中涉及到这种用法,但本人的题解思路主要借鉴了第一篇题解):

    https://blog.csdn.net/shahdza/article/details/6586430

    https://blog.csdn.net/f_zyj/article/details/51467501

    https://www.cnblogs.com/aininot260/p/9627100.html

    关于GCC优化:

    https://blog.csdn.net/u010796610/article/details/69352484

    https://blog.csdn.net/jiayanhui2877/article/details/11615471

  • 相关阅读:
    Python 更新pip报错:Could not install packages due to an EnvironmentError: [WinError 5] 拒绝访问
    Vs code 配置(1)-win10
    博客园主题--sukura
    log4j
    安装ant问题
    freemarker string= null
    学习随想
    j2ee学习资料收集
    eclipse + marven
    好文mark
  • 原文地址:https://www.cnblogs.com/Taskr212/p/9742685.html
Copyright © 2011-2022 走看看