zoukankan      html  css  js  c++  java
  • 括号序列模型--序列dp--U86873 小Y的精灵国机房之旅

    括号序列模型及解法

    >Codeforces314E
    给定一个长度为n的仅包含左右括号和问号的字符串,将问号变成左括号
    或右括号使得该括号序列合法,求方案总数。
    例如(())()()都是合法的括号序列。
    ◦ n<=3000

    >Solution

    ◦括号序列问题,往往就是把左括号看成+1,右括号看成-1,我们只需要
    保证任意一个前缀大于等于0,且总和为0,就代表是个合法括号序列了。
    dp[i][j]表示当前到第i个字符,现在的前缀和
    那么分三种情况考虑。
    若第i+1个字符是左括号,则能转移到dp[i+1][j+1]
    若第i+1个字符是右括号,则能转移到dp[i+1][j-1]
    若第i+1个字符是问号,则能转移到dp[i+1][j-1]dp[i+1][j+1]
    最终dp[n][0]就是方案总数啦。
    时间复杂度为O(n^2)

    U86873 小Y的精灵国机房之旅

    题解

    括号序列模型唉!

    所以就可以套用上面的式子啦

    把Y看做左括号,H看做右括号,C看做问号

    准备AC

    #include<iostream>
    #include<bits/stdc++.h>
    using namespace std;
    
    typedef long long ll;
    
    inline int read()
    {
        int ans=0;
        char last=' ',ch=getchar();
        while(ch<'0'||ch>'9') last=ch,ch=getchar();
        while(ch>='0'&&ch<='9') ans=ans*10+ch-'0',ch=getchar();
        if(last=='-') ans=-ans;
        return ans;
    }
    
    const int maxn=10010,mod=1e9+7;
    int n;
    char a[maxn];
    int f[3000][3000];
    
    int main()
    {
        n=read();
        scanf("%s",a+1);
        f[0][0]=1;
        for(int i=1;i<=n;i++){
            if(a[i]=='Y'){
                f[i][0]=0;
                for(int j=1;j<=i;j++){
                    f[i][j]=f[i-1][j-1];
                }
            }
            if(a[i]=='H'){
                for(int j=0;j<i;j++){
                    f[i][j]=f[i-1][j+1];
                }
                f[i][i]=0;
            }
            if(a[i]=='C'){
                for(int j=1;j<i;j++){
                    f[i][j]=(f[i-1][j-1]+f[i-1][j+1])%mod;
                }
                f[i][0]=f[i-1][1];
                f[i][i]=f[i-1][i-1];
            }
        }
        printf("%d
    ",f[n][0]%mod);
        return 0;
    }

    然后发现不对劲。。。。。

    二维数组一定会炸。。。。

    那就。。。循环队列!

    我们发现每次到新的一个 i ,它只和 i-1 有关,所以 i-1 用过一次就可以销毁了,不然也是占空间

    可以像这样&1来实现循环利用

    代码

    #include<iostream>
    #include<bits/stdc++.h>
    using namespace std;
    
    typedef long long ll;
    
    inline int read()
    {
        int ans=0;
        char last=' ',ch=getchar();
        while(ch<'0'||ch>'9') last=ch,ch=getchar();
        while(ch>='0'&&ch<='9') ans=ans*10+ch-'0',ch=getchar();
        if(last=='-') ans=-ans;
        return ans;
    }
    
    const int maxn=10010,mod=1e9+7;
    int n;
    char a[maxn];
    int f[3][maxn];
    
    int main()
    {
        n=read();
        scanf("%s",a+1);
        memset(f,0,sizeof(f));
        f[0][0]=1;
        for(int i=1;i<=n;i++){
            if(a[i]=='Y'){
                f[i&1][0]=0;
                for(int j=1;j<=i;j++){
                    f[i&1][j]=f[(i-1)&1][j-1];
                }
            }
            if(a[i]=='H'){
                for(int j=0;j<i;j++){
                    f[i&1][j]=f[(i-1)&1][j+1];
                }
                f[i&1][i]=0;
            }
            if(a[i]=='C'){
                f[i&1][0]=f[(i-1)&1][1];
                for(int j=1;j<i;j++){
                    f[i&1][j]=(f[(i-1)&1][j-1]+f[(i-1)&1][j+1])%mod;
                }
                f[i&1][i]=f[(i-1)&1][i-1];
            }
        }
        printf("%d
    ",f[n&1][0]%mod);
        return 0;
    }
  • 相关阅读:
    头文件里面的ifndef /define/endif的作用
    互联网小知识
    IT技术开发人员获得成功的六大步骤
    ab网站压力测试
    微软校招试题
    C程序编译过程浅析
    makefile变量赋值
    printf的题目
    Oracle命名规范
    javascript(js)小数精度丢失的解决方案
  • 原文地址:https://www.cnblogs.com/xiaoyezi-wink/p/11813497.html
Copyright © 2011-2022 走看看