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

 

posted @ 2020-02-23 12:06  朝暮不思  阅读(189)  评论(0编辑  收藏  举报