zoukankan      html  css  js  c++  java
  • AtCoder [AGC022E] Median Replace

    神仙题

    先考虑对于一种确定的 $01$ 串如何 $check$ 其合法

    我们可以开一个栈,从前往后遍历时对栈进行操作:

    1、当前位为 $0$ ,直接加入栈中,如果栈顶有连续的 $3$ 个 $0$ ,就将上面两个弹出(合并)

    2、当前位为 $1$ ,如果栈顶为 $1$ 且 $1$ 的个数不到 $2$ (超过 $2$ 个 $1$ 剩下的是没有什么意义的,具体原因看后面),就加入;否则如果是 $0$ 的话,就弹出这个 $0$

    为什么加入 $1$ 时栈顶为 $0$ 时可以直接弹出栈顶 ?

    其实这个操作就相当于把这个 $1$ 与栈顶的 $0$ 合并了,因为一个 $1$ 和一个 $0$ 最后合成什么还是要看第三个数是什么,所以这里可以直接弹出不管

    可以发现栈底是连续的一段 $1$ ,栈顶是连续的一段 $0$ ,且个数都不超过 $2$ 个。

    手玩一下可以发现,最后是否可行就看栈中 $1$ 的个数是不是大于等于 $0$ 的个数就行了 

    证明可以自己去推一下(懒得写了,大概就是从奇偶性下手)

    然后我们发现这个栈的状态很好描述(就是可以开个两维,第一维是有几个 $1$ ,第二维有几个 $0$ ,由上面的那条栈内数字的性质可以发现这样是可以描述唯一的一种的)

    于是直接 $ ext{DP}$ 套 $ ext{DP}$ (算套 $ ext{DP}$ 吗?反正是个 $ ext{DP}$ 就对了)

    $code$ :

    #include<cstdio>
    #include<cctype>
    #include<cstring>
    
    #define maxn 303303
    #define mod 1000000007
    
    template<class T>
    
    inline T read(){
        T r=0,f=0;
        char c;
        while(!isigit(c=getchar()))f|=(c=='-');
        while(isdigit(c))r=(r<<1)+(r<<3)+(c^48),c=getchar();
        return f?-r:r;
    }
    
    int n;
    
    char s[maxn];
    
    long long ans,f[maxn][5][5];
    
    int main(){
        scanf("%s",s+1);
        n=strlen(s+1);
        f[0][0][0]=1;
        for(int i=1;i<=n;i++)
            for(int j=0;j<3;j++)
                for(int k=0;k<3;k++){
                    if(s[i]!='0'){
                        if(k<2)(f[i][j][k]+=f[i-1][j][k+1])%=mod;
                        if(j&&!k){
                            (f[i][j][k]+=f[i-1][j-1][k])%=mod;
                            if(j==2)(f[i][j][k]+=f[i-1][j][k])%=mod;
                        }
                    }
                    if(s[i]!='1'&&k){
                        (f[i][j][k]+=f[i-1][j][k-1])%=mod;
                        if(k==1)(f[i][j][k]+=f[i-1][j][2])%=mod;
                    }
                }
        for(int i=0;i<3;i++)
            for(int j=0;j<=i;j++)
                (ans+=f[n][i][j])%=mod;
        printf("%lld
    ",ans);
        return 0;
    }
  • 相关阅读:
    自增长主键Id的另类设计
    Android 混淆那些事儿
    H5 和移动端 WebView 缓存机制解析与实战
    快速上手 Kotlin 的 11 招
    教你 Debug 的正确姿势——记一次 CoreMotion 的 Crash
    小程序组件化框架 WePY 在性能调优上做出的探究
    基于 TensorFlow 在手机端实现文档检测
    HTTPS 原理浅析及其在 Android 中的使用
    Bugly 多渠道热更新解决方案
    Swift 对象内存模型探究(一)
  • 原文地址:https://www.cnblogs.com/wyzwyz/p/14038695.html
Copyright © 2011-2022 走看看