zoukankan      html  css  js  c++  java
  • Codeforces 404D(dp)

    传送门

    题意:

    11维扫雷问题。

    给你一个长度为lenlen的字符串,每一个字符串分别有五种可能性:1100??22*‘,

    • 如果字符为11,则代表其相邻有一个*

    • 如果字符为00,则代表相邻没有*

    • 如果字符为22,则代表相邻有两个*

    • 如果字符为*,则代表此处是地雷

    • 如果字符为??,则代表有该字符能够表示为其他四种字符。

    现在问你给定的字符串中能够表示多少种正确的扫雷图。并对答案mod  109+7mod10^9+7

    题解:

    刚拿到这个题就觉得这个题很dpdp,奈何dpdp还是弱项dots dots

    我们分析,对于除了??的四种字符,要使得原来的串合法,则必定需要满足:

    如果当前的字符为00,则其前面必定要是00或者1*1

    如果当前的字符为22,则其前面必定要是*

    如果当前的字符为*,则其前面必定*或者22或者0101

    如果当前的字符为11,则前面可能是00亦可能是*

    我们发现,此时,我们可以将上述的合法条件设置成44个不同的状态,即分别为:

    010120 quad *1 quad 01 quad 2 quad *

    我们发现,其他的合法的状态必定可以通过增加某个字符达到上诉4个状态。

    因此我们设dp[i][j]dp[i][j]代表前ii个字符串中,当前处于状态jj时的可能性。

    而根据上述的合理条件,我们不难写出一下几条状态转移方程:

    如果当前字符为00,有
    dp[i][0]+=dp[i1][0]dp[i][0]+=dp[i1][1]dp[i][0]+=dp[i-1][0]quad || quad dp[i][0]+=dp[i-1][1]

    如果当前字符为22,有
    dp[i][3]+=dp[i1][4]dp[i][3]+=dp[i-1][4]

    如果当前字符为*,有
    dp[i][4]+=dp[i1][2]dp[i][4]+=dp[i1][3]dp[i][4]+=dp[i1][4]dp[i][4]+=dp[i-1][2] quad || quad dp[i][4]+=dp[i-1][3] quad ||quad dp[i][4]+=dp[i-1][4]

    如果当前字符为11,有
    dp[i][1]+=dp[i1][4]dp[i][2]+=dp[i1][0]dp[i][2]+=dp[i1][1]dp[i][1]+=dp[i-1][4] quad || quad dp[i][2]+=dp[i-1][0] quad || quad dp[i][2]+=dp[i-1][1]

    最后如果当前的字符为??显然上述可能性均有。

    最后我们需要注意开头和结尾位置的特判。

    当处于开头时,显然只存在*00的状态。

    而位于结尾时,显然只存在*001*1的状态。

    最后只需要线性转移并统计答案即可。

    #include <bits/stdc++.h>
    #define maxn 1000005
    using namespace std;
    char str[maxn];
    int dp[maxn][6];
    const int mod=1e9+7;
    typedef long long ll;
    int main()
    {
        scanf("%s",str);
        int len=strlen(str);
        if(str[0]=='?') dp[0][0]=1,dp[0][2]=1,dp[0][4]=1;
        if(str[0]=='0') dp[0][0]=1;
        if(str[0]=='*') dp[0][4]=1;
        if(str[0]=='1') dp[0][3]=1;
        for(int i=1;i<len;i++){
            if(str[i]=='0'||str[i]=='?'){
                dp[i][0]=(dp[i][0]+dp[i-1][0])%mod;
                dp[i][0]=(dp[i][0]+dp[i-1][1])%mod;
            }
            if(str[i]=='1'||str[i]=='?'){
                dp[i][1]=(dp[i][1]+dp[i-1][4])%mod;
                dp[i][2]=(dp[i][2]+dp[i-1][0])%mod;
                dp[i][2]=(dp[i][2]+dp[i-1][1])%mod;
            }
            if(str[i]=='2'||str[i]=='?'){
                dp[i][3]=(dp[i][3]+dp[i-1][4])%mod;
            }
            if(str[i]=='*'||str[i]=='?'){
                dp[i][4]=(dp[i][4]+dp[i-1][2])%mod;
                dp[i][4]=(dp[i][4]+dp[i-1][3])%mod;
                dp[i][4]=(dp[i][4]+dp[i-1][4])%mod;
            }
        }
        ll res=dp[len-1][0]+dp[len-1][1];
        res%=mod;
        res=(res+dp[len-1][4])%mod;
        cout<<res<<endl;
    }
    
    
  • 相关阅读:
    最长公共子序列和最长公共连续子序列 andrew的日志 网易博客
    Best Computer Science Interview Books JiansNet
    分享:Mitmproxy 0.9 发布,支持 SSL 的 HTTP 代理
    创业环境差,被迫“走西口”:一位台湾码农的心路历程
    STLSupport GDB Wiki
    utils C/C++的常用工具类
    题目36 ACM在线评测系统
    DRAMA QUEEN_洪晃在ilook的BLOG
    Codeblocks调试STL——gdb with python support Wanglikai91 博客园
    python urlencode 编码
  • 原文地址:https://www.cnblogs.com/Chen-Jr/p/11007157.html
Copyright © 2011-2022 走看看