• codeforce 149D Coloring Brackets 区间DP


    题目链接:http://codeforces.com/problemset/problem/149/D

    继续区间DP啊。。。。

    思路:

    定义dp[l][r][c1][c2]表示对于区间(l,r)来说,l用c1染色,r用c2染色的方案数。

    那么:

    1,如果括号l和括号r匹配(即括号l和r为一对括号)那么dp[l][r][c1][c2]+=dp[l+1][r-1][i][j](i与c1为不同的颜色,j与c2是不同的颜色,或i=0或j=0)

    2,如果括号l和括号r不匹配,那么dp[l][r][c1][c2]+=dp[l][m(l)][c1][i]*dp[m(l)+1][r][j][c2];(i与c1为不同的颜色或i=0,j与c2不同,或j=0)(m(l))表示与l匹配的右括号的位置

    代码实现,我用的是记忆化搜索的方式:

     1 #include<iostream>
     2 #include<cstdlib>
     3 #include<cstdio>
     4 #include<stack>
     5 #include<cstring>
     6 using namespace std;
     7 char s[710];
     8 stack<int>q;
     9 int n;
    10 int m[710];
    11 long long int dp[710][710][3][3];
    12 long long int ans;
    13 #define MOD 1000000007
    14 void init()
    15 {
    16         memset(m,0,sizeof(m));
    17         memset(dp,-1,sizeof(dp));
    18         ans=0;
    19 }
    20 void Match_Bracks()
    21 {
    22         while(!q.empty()) q.pop();
    23         for(int i=0;i<n;i++)
    24         {
    25              if(s[i]=='(') q.push(i);
    26              else
    27                  {
    28                    int k=q.top();
    29                    m[k]=i;
    30                    q.pop();
    31                  }
    32         }
    33 }
    34 bool check(int a,int b)
    35 {
    36         if(a==0||b==0||a!=b) return true;
    37         return false;
    38 }
    39 int kk=0;
    40 long long int dfs(int l,int r,int  c1,int c2)
    41 {
    42         long long int sum=0;
    43 
    44         if(dp[l][r][c1][c2]>=0) return dp[l][r][c1][c2];
    45        if(m[l]==r&&r)
    46        {
    47                if((c1==0&&c2)||(c2==0&&c1))
    48                {
    49                   if(l+1==r)
    50                     return dp[l][r][c1][c2]=1;
    51                        for(int i=0;i<3;i++)
    52                          for(int j=0;j<3;j++)
    53                            if(check(i,c1)&&check(j,c2))
    54                                 sum=(sum+dfs(l+1,r-1,i,j)%MOD)%MOD;                               
    55                }
    56                else return dp[l][r][c1][c2]=0;
    57        }
    58        else
    59            {
    60               for(int i=0;i<3;i++)
    61                 for(int  j=0;j<3;j++)
    62                   if(check(i,j))
    63                      sum=(sum+dfs(l,m[l],c1,i)*dfs(m[l]+1,r,j,c2)%MOD)%MOD;
    64            }
    65             return  dp[l][r][c1][c2]=sum%MOD;
    66 }
    67 int main()
    68 {
    69         while(scanf("%s",s)!=EOF)
    70         {
    71                init();
    72                n=strlen(s);
    73                Match_Bracks();
    74               for(int i=0;i<3;i++)
    75                   for(int j=0;j<3;j++)
    76                       ans=(ans+dfs(0,n-1,i,j)%MOD)%MOD;
    77                  cout<<ans<<endl;
    78          }
    79         return 0;
    80 }
    View Code
  • 相关阅读:
    awk 使用shell 变量
    设计模式之 外观(门面)模式 Facade
    设计模式之 抽象工厂模式
    python 第一课
    Visual Basic 图片连接地址添加
    smarty 不同模板 缓存时间
    PHP 传参过滤
    Nginx 0.7.x + PHP 5.2.10(FastCGI)搭建支持高并发量的Web服务器
    linux vi 编辑命令
    PHP 命令模式 执行文件 并传递参数
  • 原文地址:https://www.cnblogs.com/xiaozhuyang/p/codefroce149D.html
Copyright © 2020-2023  润新知