zoukankan      html  css  js  c++  java
  • CF149D Coloring Brackets (区间dp)

    本题一个很巧妙的设计就是dp状态,设计为f[l][r][i][j],从l-r,左右端点是哪个

    这样就可以通过递归来计算小区间的值

    记住,要先进行字符串的匹配,也就是常规的括号进出栈问题,记录下来每个左括号匹配的右括号的位置

    网上有些记录了右括号的匹配左括号是谁,其实没有必要,因为用不大,大概是因为第一个多写了这步,后面的人就懒得改了

    #include<algorithm>
    #include<iostream>
    #include<cstdio>
    #include<vector>
    #include<cstring>
    #include<set>
    #include<map>
    using namespace std;
    typedef long long ll;
    const int N=1100;
    const int mod=1e9+7;
    ll f[N][N][3][3]; 
    int st[N];
    int tmp[N];
    void dfs(int l,int r){
        if(l+1==r){
            f[l][r][0][1]=1;
            f[l][r][1][0]=1;
            f[l][r][0][2]=1;
            f[l][r][2][0]=1;
            return ;
        }
        else if(st[l]==r){
            dfs(l+1,r-1);
            int i,j;
            for(i=0;i<3;i++){
                for(j=0;j<3;j++){
                    if(j!=1)
                    f[l][r][0][1]=(f[l][r][0][1]+f[l+1][r-1][i][j])%mod;
                    if(i!=1)
                    f[l][r][1][0]=(f[l][r][1][0]+f[l+1][r-1][i][j])%mod;
                    if(j!=2)
                    f[l][r][0][2]=(f[l][r][0][2]+f[l+1][r-1][i][j])%mod;
                    if(i!=2)
                    f[l][r][2][0]=(f[l][r][2][0]+f[l+1][r-1][i][j])%mod; 
                }
            }
            return ;
        }
        else{
            int p=st[l];
            dfs(l,p);
            dfs(p+1,r);
            int i,j,k,q;
            for(i=0;i<3;i++){
                for(j=0;j<3;j++){
                    for(k=0;k<3;k++){
                        for(q=0;q<3;q++){
                            if(k!=q||(!k&&!q)){
                                f[l][r][i][j]=(f[l][r][i][j]+f[l][p][i][k]*f[p+1][r][q][j]%mod)%mod;
                            }
                        }
                    }
                    f[l][r][i][j]%=mod;
                }
            }
        }
        
    }
    int main(){
        int i;
        string s;
        cin>>s;
        int cnt=0;
        memset(f,0,sizeof f);
        for(i=0;i<s.size();i++){
            if(s[i]=='(')
            tmp[cnt++]=i;
            else{
                st[tmp[cnt-1]]=i;
                cnt--;
            }
        }
        int len=s.size()-1;
        dfs(0,len);
        ll ans=0;
        int j;
        for(i=0;i<3;i++){
            for(j=0;j<3;j++){
                ans=(ans+f[0][len][i][j])%mod;
            }
        }
        cout<<ans<<endl;
           return 0;
    }
    View Code
  • 相关阅读:
    素材收集
    网站返回503
    uva 1048 最短路的建图 (巧,精品)
    hdu5188 01 背包
    hdu 5187 快速幂 + 快速乘 值得学习
    差分约束
    uva11090 Bellman-Ford 运用
    hdu 5185 动态规划 分析降低复杂度
    hdu5184 数论证明
    HDU5183 hash 表
  • 原文地址:https://www.cnblogs.com/ctyakwf/p/12349089.html
Copyright © 2011-2022 走看看