zoukankan      html  css  js  c++  java
  • Codeforces Round #106 (Div. 2) Coloring Brackets(区间DP)

    题意:给你一组括号序列,让你进行染色,对于每个括号,有无色,红色,蓝色三种方案。染色需要满足这样的条件:互相匹配的括号,有且只有一个有颜色,相邻的括号不能颜色相同(可以同为无色),问合法的染色方案数(答案%1e9+7)

    分析:根据题意能够看出是区间DP,并且状态转移的时候,依赖于左右两端的颜色,所以我们用dp[i][j][x][y]表示i到j的区间内左端颜色为x,右端颜色为y的方案数。

            区间[i,j]可以由两种情况得到,一种是str[i],str[j]匹配,产生新的相匹配的括号,考虑在只有一端染色的情况下,由[i+1][j-1]的状态转移得到

             二是由已经匹配好的两个区间得到,这里,我们可以先用栈预处理出,括号的匹配对应关系,这样就能找到匹配好的区间位置。

    代码如下:

    #include <cstdio>
    #include <iostream>
    #include <algorithm>
    #include <cstring>
    #include <vector>
    #include <queue>
    #include <functional>
    #include  <map>
    #include <vector>
    #include <stack>
    using namespace std;
    #define INF 100000000
    typedef long long LL;
    stack<int>S;
    const int MOD=1e9+7;
    LL dp[710][710][3][3];
    LL to[710];
    char str[710];
    int main()
    {
        scanf("%s",str+1);
        int len=strlen(str+1);
        for(int i=1;i<=len;i++)
        {
            if(str[i]=='(')
            S.push(i);
            else
            {
               int x=S.top();
               to[i]=x;
               to[x]=i;
               S.pop();
            }
        }
        for(int i=1;i<=len-1;i++)
        {
           if(str[i]=='('&&str[i+1]==')')
           {
             dp[i][i+1][1][0]=1;
             dp[i][i+1][2][0]=1;
             dp[i][i+1][0][1]=1;
             dp[i][i+1][0][2]=1;
           }
        }
    
        for(int l=3;l<=len-1;l+=2)
            for(int i=1;i<=len-l;i++)
        {
            int j=i+l;
            if(str[i]=='('&&str[j]==')')
            {
                dp[i][j][1][0]+=(dp[i+1][j-1][2][0]+dp[i+1][j-1][2][1]+dp[i+1][j-1][2][2]+dp[i+1][j-1][0][1]+dp[i+1][j-1][0][2]+dp[i+1][j-1][0][0]);
                dp[i][j][1][0]%=MOD;
    
                dp[i][j][2][0]+=(dp[i+1][j-1][1][0]+dp[i+1][j-1][1][1]+dp[i+1][j-1][1][2]+dp[i+1][j-1][0][1]+dp[i+1][j-1][0][2]+dp[i+1][j-1][0][0]);
                dp[i][j][2][0]%=MOD;
    
                dp[i][j][0][1]+=(dp[i+1][j-1][0][2]+dp[i+1][j-1][1][2]+dp[i+1][j-1][2][2]+dp[i+1][j-1][1][0]+dp[i+1][j-1][2][0]+dp[i+1][j-1][0][0]);
                dp[i][j][0][1]%=MOD;
    
                dp[i][j][0][2]+=(dp[i+1][j-1][0][1]+dp[i+1][j-1][1][1]+dp[i+1][j-1][2][1]+dp[i+1][j-1][1][0]+dp[i+1][j-1][2][0]+dp[i+1][j-1][0][0]);
                dp[i][j][0][2]%=MOD;
            }
               int k=to[i];
                for(int x=0;x<3;x++)
                    for(int y=0;y<3;y++)
                {
                      LL res=0;
                      for(int q1=0;q1<3;q1++)
                         for(int q2=0;q2<3;q2++)
                      {
                          if(q1==q2&&q1!=0)continue;
                          res=(res+dp[i][k][x][q1]*dp[k+1][j][q2][y])%MOD;
                      }
                     dp[i][j][x][y]=max(dp[i][j][x][y],res);
                }
        }
    
         LL ans=0;
        for(int i=0;i<=2;i++)
         for(int j=0;j<=2;j++)
        {
            ans+=dp[1][len][i][j];
        }
        printf("%lld
    ",ans%MOD);
        return 0;
    }
  • 相关阅读:
    Spring MVC:框架及其组件介绍
    Goods:生成订单
    Goods:我的订单查询分页
    LeetCode:Kth Largest Element in an Array(need update)
    LeetCode:Swap Nodes in Pairs
    Goods:购物车条目加减数量实现
    LeetCode:Sum Root to Leaf Numbers
    Goods:购物车模块之全选按钮与条目之复选按钮的click事件
    Goods:查询某个用户的购物车条目以及添加购物车条目
    洛谷2387 NOI2014魔法森林(LCT维护最小生成树)
  • 原文地址:https://www.cnblogs.com/a249189046/p/9668200.html
Copyright © 2011-2022 走看看