• 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 }
  • 相关阅读:
    LeetCode对撞指针汇总
    167. Two Sum II
    215. Kth Largest Element in an Array
    2018Action Recognition from Skeleton Data via Analogical Generalization over Qualitative Representations
    题解 Educational Codeforces Round 84 (Rated for Div. 2) (CF1327)
    题解 JZPKIL
    题解 八省联考2018 / 九省联考2018
    题解 六省联考2017
    题解 Codeforces Round #621 (Div. 1 + Div. 2) (CF1307)
    题解Codeforces Round #620 (Div. 2)
  • 原文地址:https://www.cnblogs.com/zhang-Kelly/p/12685038.html
Copyright © 2020-2023  润新知