Codeforces 149D Coloring Brackets

http://codeforces.com/contest/149/problem/D

题目描述:

  给一个合法的括号串,然后问这串括号有多少种涂色方案,当然啦!涂色是有限制的。

  1,每个括号只有三种选择:涂红色,涂蓝色,不涂色。

  2,每对括号有且仅有其中一个被涂色。

  3,相邻的括号不能涂相同的颜色,但是相邻的括号可以同时不涂色。

思路:dp:f[i][j][k][l]代表i到j这个区间,左边为k颜色,右边为l颜色

 

#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<iostream>
#define ll long long
const ll Mod=1000000007;
int id[200005],n;
ll f[705][705][3][3];
int c[200005];
char s[200005];
int read(){
    int t=0,f=1;char ch=getchar();
    while (ch<'0'||ch>'9'){if (ch=='-') f=-1;ch=getchar();}
    while ('0'<=ch&&ch<='9'){t=t*10+ch-'0';ch=getchar();}
    return t*f;
}
void dp(int L,int R){
    if (L>R) return;
    if (L+1==R){
        f[L][R][0][0]=0;f[L][R][0][1]=1;f[L][R][0][2]=1;f[L][R][1][0]=1;f[L][R][2][0]=1;f[L][R][1][1]=0;f[L][R][2][2]=0;f[L][R][2][1]=0;f[L][R][1][2]=0;
        return;
    }
    if (id[L]==R){
        dp(L+1,R-1);
        for (int i=0;i<3;i++)
         for (int j=0;j<3;j++)
          if (((i>0)^(j>0)))
          for (int k=0;k<3;k++)
           for (int l=0;l<3;l++)
            if ((i==0||k==0||i!=k)&&(j==0||l==0||j!=l))
            (f[L][R][i][j]+=f[L+1][R-1][k][l])%=Mod;
        return;    
    }
    dp(L,id[L]);
    dp(id[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 l=0;l<3;l++)
        if (j==0||k==0||j!=k)
         (f[L][R][i][l]+=(f[L][id[L]][i][j]*f[id[L]+1][R][k][l])%Mod)%=Mod;
}
int main(){
    scanf("%s",s+1);n=strlen(s+1);
    int top=0;
    for (int i=1;i<=n;i++){
        if (s[i]=='(') c[++top]=i;
        else id[c[top--]]=i;
    }
    dp(1,n);
    ll Ans=0;
    for (int i=0;i<3;i++)
     for (int j=0;j<3;j++)
     Ans=(Ans+f[1][n][i][j])%Mod;
    printf("%I64d
",Ans);
}

 

 

原文地址:https://www.cnblogs.com/qzqzgfy/p/5667121.html