区间dp好题cf149d 括号匹配

见题解链接https://blog.csdn.net/sdjzping/article/details/19160013

#include<bits/stdc++.h>
using namespace std;
#define maxn 750
#define mod 1000000007
int len,p[maxn];
long long dp[maxn][maxn][3][3];
char s[maxn];
void match(){
    stack<int>stk;
    while(!stk.empty())stk.pop();
    for(int i=0;i<len;i++){
        if(stk.empty()){
            stk.push(i);
            continue;
        }
        int t=stk.top();
        if(s[i]==')'&&s[t]=='('){
            p[t]=i,p[i]=t;
            stk.pop();
        }
        else stk.push(i);
    }
}
void dfs(int l,int r){
    if(l==r)return;
    if(l+1==r){//只有一种情况 
        dp[l][r][0][1]=dp[l][r][1][0]=dp[l][r][0][2]=dp[l][r][2][0]=1; 
        return; 
    }
    if(p[l]==r){//配对了 
        dfs(l+1,r-1);
        for(int i=0;i<3;i++)
            for(int j=0;j<3;j++){
                if(j!=1)dp[l][r][0][1]=(dp[l][r][0][1]+dp[l+1][r-1][i][j])%mod;
                if(j!=2)dp[l][r][0][2]=(dp[l][r][0][2]+dp[l+1][r-1][i][j])%mod;
                if(i!=1)dp[l][r][1][0]=(dp[l][r][1][0]+dp[l+1][r-1][i][j])%mod;
                if(i!=2)dp[l][r][2][0]=(dp[l][r][2][0]+dp[l+1][r-1][i][j])%mod;
            }
        return;
    }
    //剩下的情况就是不能配对的情况
    int tmp=p[l];
    dfs(l,tmp);dfs(tmp+1,r);
    for(int i=0;i<3;i++)
        for(int j=0;j<3;j++)
            for(int k=0;k<3;k++)
                for(int m=0;m<3;m++)
                    if(!((k==1 && m==1) || (k==2 && m==2)))
                    dp[l][r][i][j]=(dp[l][r][i][j]+(dp[l][tmp][i][k]*dp[tmp+1][r][m][j])%mod)%mod; 
}

int main(){
    cin>>s;len=strlen(s);
    memset(dp,0,sizeof dp);
    match();dfs(0,len-1);
    long long  ans=0;
    for(int i=0;i<3;i++)
        for(int j=0;j<3;j++)
            ans=(ans+dp[0][len-1][i][j])%mod;
    printf("%lld\n",ans);
}

 

posted on 2019-01-24 18:14  zsben  阅读(181)  评论(0编辑  收藏  举报

导航