Codeforces Round #106 (Div. 2), problem: (D) Coloring Brackets 区间DP+组合

来源:互联网 发布:英文名与中文名 知乎 编辑:程序博客网 时间:2024/05/01 14:18

题意:给括号对染色,这里的括号对的确定必须是括号a,b之间必须是没有括号,或者是还有完整的括号

做法:区间DP,先使最小的括号染色,然后根据区间两端是否可以匹配,进行分别计算。

#include <iostream>#include <cstdio>#include <cstring>#include <stack>#define LL long long#define mod  1000000007const int LMT=705;using namespace std;char str[LMT];LL dp[LMT][LMT][3][3];//定义的时候要小心啊...bool is[LMT][LMT];int main(){    int len;    LL ans=0;    stack<int>q;    scanf("%s",str);    len=strlen(str);    for(int i=0;i<len;i++)    if(str[i]=='(')q.push(i);    else    {        is[q.top()][i]=1;        q.pop();    }    for(int i=0;i<len-1;i++)    if(is[i][i+1])    { dp[i][i+1][0][1]=dp[i][i+1][0][2]       =dp[i][i+1][1][0]=dp[i][i+1][2][0]=1;    }    for(int k=3;k<=len;k++)      for(int i=0,j;i+k-1<len;i++)      {          j=i+k-1;          if(is[i][j])//能盖就盖吧          {           for(int c10=0;c10<3;c10++)            for(int c01=0;c01<3;c01++)            if((c10||c01)&&c10*c01==0)              for(int c20=0;c20<3;c20++)              if(c20!=c10||c20*c10==0)                for(int c02=0;c02<3;c02++)                if(c01!=c02||c01*c02==0)                {                    dp[i][j][c10][c01]+=dp[i+1][j-1][c20][c02];                    dp[i][j][c10][c01]%=mod;                }          }           else if(str[i]=='('&&str[j]==')')           {               int kk;               for(kk=i;kk<=j&&!is[i][kk];kk++);             if(kk<=j)               for(int c10=0;c10<3;c10++)                 for(int c01=0;c01<3;c01++)                  for(int c20=0;c20<3;c20++)                  if(c20!=c01||c20*c01==0)                     for(int c02=0;c02<3;c02++)                     {                         dp[i][j][c10][c02]+=dp[i][kk][c10][c01]*dp[kk+1][j][c20][c02];                         dp[i][j][c10][c02]%=mod;                     }           }      }      for(int c10=0;c10<3;c10++)        for(int c01=0;c01<3;c01++)        {            ans+=dp[0][len-1][c10][c01];            ans%=mod;        }        printf("%I64d\n",ans);    return 0;}


原创粉丝点击