首页 > 其他分享 >CF149D Coloring Brackets

CF149D Coloring Brackets

时间:2022-10-30 18:11:30浏览次数:40  
标签:maxx Coloring Brackets int CF149D 括号 染色 dp define

题意:给出一串合法括号,按以下规则给括号染色:

1. 每个符号可以染红色、蓝色,或者不染色;

2. 相邻两个符号不能染同一种颜色,可以都不染色;

3. 一对括号有且仅有一个符号染色。

求染色方案数。

解:状态很好设啦,dp[i][j][0/1/2][0/1/2]表示区间[i, j]两边分别染什么颜色。转移不能像一般区间dp一样枚举区间长度,因为一对括号要一起考虑。用递归来转移,从小到大处理合法的状态。最小的状态是()。如果一个区间的两端刚好是一对括号,继承括号里的内容;如果不是,它一定能分成两组合法的括号,分别求解小区间的答案,然后用乘法定理。没事多加几个取模。

代码:

#include <bits/stdc++.h>
using namespace std;
#define maxx 705
#define maxn 25
#define maxm 205
#define ll long long
#define inf 1000000009
#define mod 1000000007
ll dp[maxx][maxx][3][3]={0};
char s[maxx];
int c[maxx]={0};
int n;
void dfs(int l, int r){
    if(l+1==r){
        dp[l][r][0][1]=dp[l][r][0][2]=dp[l][r][1][0]=dp[l][r][2][0]=1;
    }
    else if(c[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;
            }
        }
    }
    else{
        dfs(l,c[l]);
        dfs(c[l]+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(j==k&&j!=0) continue;
                        dp[l][r][i][m]=(dp[l][r][i][m]+((dp[l][c[l]][i][j]*dp[c[l]+1][r][k][m])%mod))%mod;
                    }
                }
            }
        }
    }
}
signed main() {
//    int T;
//    scanf("%d",&T);
//    while(T--) {;
//
//    }
    scanf("%s",s+1);
    n=strlen(s+1);
    stack<int> st;
    for(int i=1;i<=n;i++){
        if(s[i]=='(') st.push(i);
        else{
            c[st.top()]=i;
            c[i]=st.top();
            st.pop();
        }
    }
    dfs(1,n);
    ll ans=0;
    for(int i=0;i<3;i++){
        for(int j=0;j<3;j++){
            ans=(ans+dp[1][n][i][j])%mod;
        }
    }
    printf("%lld\n",ans);
    return 0;
}
View Code

 

 

标签:maxx,Coloring,Brackets,int,CF149D,括号,染色,dp,define
From: https://www.cnblogs.com/capterlliar/p/16841845.html

相关文章

  • 【XSY3270】Domino Colorings(轮廓线dp,状压)
    若已经知道了每个格子的颜色,我们可以用轮廓线DP(类似插头DP)判断棋盘是否能被多米诺骨牌填满,设\(dp[S]\)表示是否存在某种填法使得轮廓线每个位置是否被填的状态为\(S\)......
  • CF380C Sereja and Brackets 题解 数列分块
    题目链接:​​https://codeforces.com/contest/380/problem/C​​题目大意:给定长度为\(n(\le10^6)\)的一个括号序列,有\(m(\le10^5)\)次询问,每次询问给定一个区间\([l,......
  • CF1329A Dreamoon Likes Coloring 题解
    提供一个简短的题解:首先如果所有长度加起来还不到\(n\)直接无解。可以直接贪心,把第\(i\)条线段的右端点放在\(n-i+1\)这个位置,就可以最省长度(只占一个点)而且不会遗......
  • CF149D Coloring Brackets
    #include<bits/stdc++.h>usingnamespacestd;#defineintlonglongclasssolve{ public: chars[777]; intf[1000][1000][3][3]; intmod; intothers[1000......
  • POJ2955 Brackets
    题目链接题目DescriptionWegivethefollowinginductivedefinitionofa“regularbrackets”sequence:theemptysequenceisaregularbracketssequence,ifs......