• Coloring Brackets CF-149D(区间DP)


    题意:

    给定合法括号序列,可以给括号涂三种颜色:红色,蓝色,不上色。涂色需要满足以下两个要求:

    ①匹配括号必须一个上色一个不上色。

    ②相邻括号不能上同一种颜色,但可以同时不上色。

    求上色方案数。

    思路:

    $dp[i][j][k][l]$表示区间$(i,j)$中$i$上颜色$k$,$j$上颜色$l$的方案数。分三种情况:

    ①$i$和$j$相邻,则可以保证$i$和$j$匹配,那么$dp[i][j][0][1]=dp[i][j][0][2]=dp[i][j][1][0]=dp[i][j][2][0]=1$。

    ②$i$和$j$匹配,递归求得$dp[i+1][j-1][k][l]$的相应的方案数,转移得到:

      $dp[i][j][0][1] += dp[i + 1][j - 1][k][0] + dp[i + 1][j - 1][k][2]$

      $dp[i][j][0][2] += dp[i + 1][j - 1][k][0] + dp[i + 1][j - 1][k][1]$

      $dp[i][j][1][0] += dp[i + 1][j - 1][0][k] + dp[i + 1][j - 1][2][k]$

      $dp[i][j][2][0] += dp[i + 1][j - 1][0][k] + dp[i + 1][j - 1][1][k]$

    ③$i$和$j$不匹配,那么找到i的匹配点,将$(i,j)$区间拆分成$(i,mat[i])$和$(mat[i]+1,j)$,可以保证,每个区间内可以找到自己的匹配,不存在交叉匹配。

      $dp[i][j][k][l]=dp[i][mat[i]][k][u]*dp[mat[i]+1][j][o][l]$

    代码:

     1 //#include<bits/stdc++.h>
     2 #include <set>
     3 #include <map>
     4 #include <stack>
     5 #include <cmath>
     6 #include <queue>
     7 #include <cstdio>
     8 #include <string>
     9 #include <vector>
    10 #include <cstring>
    11 #include <iostream>
    12 #include <algorithm>
    13  
    14 #define ll long long
    15 #define pll pair<ll,ll>
    16 #define pii pair<int,int>
    17 #define bug printf("*********
    ")
    18 #define FIN freopen("input.txt","r",stdin);
    19 #define FON freopen("output.txt","w+",stdout);
    20 #define IO ios::sync_with_stdio(false),cin.tie(0)
    21 #define ls root<<1
    22 #define rs root<<1|1
    23 #define Q(a) cout<<a<<endl
    24  
    25 using namespace std;
    26 const int inf = 2e9 + 7;
    27 const ll Inf = 1e18 + 7;
    28 const int maxn = 700 + 5;
    29 const int mod = 1e9 + 7;
    30  
    31 char s[maxn];
    32 int mat[maxn];
    33 ll dp[maxn][maxn][5][5];
    34 stack<int>sta;
    35  
    36 void DP(int i, int j)
    37 {
    38     if (i + 1 == j)//最小括号
    39     {
    40         for (int k = 1; k <= 2; ++k) dp[i][j][k][0] = dp[i][j][0][k] = 1;
    41         return;
    42     }
    43     if (mat[i] == j)//匹配的括号
    44     {
    45         DP(i + 1, j - 1);
    46         for (int k = 0; k <= 2; ++k)
    47         {
    48             dp[i][j][0][1] += dp[i + 1][j - 1][k][0] + dp[i + 1][j - 1][k][2];
    49             dp[i][j][0][2] += dp[i + 1][j - 1][k][0] + dp[i + 1][j - 1][k][1];
    50             dp[i][j][1][0] += dp[i + 1][j - 1][0][k] + dp[i + 1][j - 1][2][k];
    51             dp[i][j][2][0] += dp[i + 1][j - 1][0][k] + dp[i + 1][j - 1][1][k];
    52         }
    53         dp[i][j][0][1] %= mod;
    54         dp[i][j][0][2] %= mod;
    55         dp[i][j][1][0] %= mod;
    56         dp[i][j][2][0] %= mod;
    57         return;
    58     }
    59     //划分区间,两个区间不存在交叉匹配
    60     DP(i, mat[i]);
    61     DP(mat[i] + 1, j);
    62     for (int k = 0; k <= 2; ++k)
    63         for (int l = 0; l <= 2; ++l)
    64             for (int u = 0; u <= 2; ++u)
    65                 for (int o = 0; o <= 2; ++o)
    66                 {
    67                     if (l == u && l != 0)   continue;
    68                     dp[i][j][k][o] += dp[i][mat[i]][k][l] * dp[mat[i] + 1][j][u][o];
    69                     dp[i][j][k][o] %= mod;
    70                 }
    71 }
    72  
    73 int main()
    74 {
    75     memset(dp, 0, sizeof dp);
    76     scanf("%s", s);
    77     int len = strlen(s);
    78     for (int i = 0; i < len; ++i)//配对
    79     {
    80         if (s[i] == '(')    sta.push(i);
    81         if (s[i] == ')')
    82         {
    83             mat[i] = sta.top();
    84             mat[sta.top()] = i;
    85             sta.pop();
    86         }
    87     }
    88     DP(0, len-1);
    89     ll ans = 0;
    90     for(int i=0;i<=2;++i)
    91         for (int j = 0; j <= 2; ++j)
    92         {
    93             ans += dp[0][len - 1][i][j];
    94             ans %= mod;
    95         }
    96     printf("%lld
    ", ans);
    97 }
  • 相关阅读:
    4111130工作总结
    js enumerations 01
    有角度地事件解读,有品质地视觉呈现。《视界》
    Mule 入门之:环境搭建
    Date 对象用于处理日期和时间
    JS脚本,时间判断问题
    丈夫道(zhuan)
    查看IP连接netstat
    二代支付简介
    对付网页无法复制的最简单绝招 ( 转)
  • 原文地址:https://www.cnblogs.com/zhang-Kelly/p/12685038.html
Copyright © 2020-2023  润新知