• CodeForces 149D 区间DP Coloring Brackets


    染色有三个条件:

    • 对于每个点来说要么不染色,要么染红色,要么染蓝色
    • 对于每对配对的括号来说,有且只有一个一边的括号被染色
    • 相邻的括号不能染成相同的颜色

    首先可以根据给出的括号序列计算出括号的配对情况,具体来说就是第i个括号与R[i]个括号配对。

    对于一个正规配对括号序列(correct bracket sequence),d(l, r, c1, c2)表示括号序列S[i]~S[j],i左边括号的颜色是c1,r右边的括号颜色是c2(0表示没有染色),这样的序列的染色方法数。

    与S[i]配对的可能是S[j],但也可能是S[k] (i < k < j)

    考虑用颜色c染这个序列的左括号还是右括号:

    • 染左括号S[i]的话,只要c与c1不同即可。得到的方案数为d(i+1, k-1, c, 0) * d(k+1, r, 0, c2)
    • 染与S[i]配对的右括号的话,要么所染S[j]的颜色c与c2不同,要么与S[i]配对的是S[k] (因为S[k]不受约束,可以染任意颜色)。得到的方案数为d(i+1, k-1, 0, c) * d(k+1, j, c, c2)
     1 #include <iostream>
     2 #include <cstdio>
     3 #include <cstring>
     4 #include <algorithm>
     5 
     6 using namespace std;
     7 
     8 typedef long long LL;
     9 
    10 const int maxn = 700 + 10;
    11 
    12 const LL M = 1000000007LL;
    13 LL d[maxn][maxn][3][3];
    14 
    15 char s[maxn];
    16 
    17 int R[maxn], S[maxn];
    18 
    19 LL DP(int l, int r, int c1, int c2)
    20 {
    21     if(l > r) return 1LL;
    22     LL& ans = d[l][r][c1][c2];
    23     if(ans >= 0) return ans;
    24     ans = 0;
    25 
    26     int k = R[l];
    27     for(int c = 1; c <= 2; c++)
    28     {
    29         if(k < r || c != c2)    //color right
    30             ans = (ans + DP(l + 1, k - 1, 0, c) * DP(k + 1, r, c, c2)) % M;
    31         if(c != c1)             //color left
    32             ans = (ans + DP(l + 1, k - 1, c, 0) * DP(k + 1, r, 0, c2)) % M;
    33     }
    34 
    35     return ans;
    36 }
    37 
    38 int main()
    39 {
    40     scanf("%s", s);
    41     int n = strlen(s);
    42 
    43     int top = 0;
    44     for(int i = 0; i < n; i++)
    45     {
    46         if(s[i] == '(') S[top++] = i;
    47         else R[S[--top]] = i;
    48     }
    49 
    50     memset(d, -1, sizeof(d));
    51     printf("%I64d
    ", DP(0, n - 1, 0, 0));
    52 
    53     return 0;
    54 }
    代码君
  • 相关阅读:
    bzoj3997 [TJOI2015]组合数学
    bzoj1143 [CTSC2008]祭祀river
    bzoj 2208 [Jsoi2010]连通数
    bzoj3713 [PA2014]Iloczyn
    bzoj1054 [HAOI2008]移动玩具
    习题6-5 使用函数验证哥德巴赫猜想(20 分)
    习题6-4 使用函数输出指定范围内的Fibonacci数(20 分)
    习题6-3 使用函数输出指定范围内的完数(20 分)
    习题6-2 使用函数求特殊a串数列和(20 分)
    分类统计字符个数(15 分)
  • 原文地址:https://www.cnblogs.com/AOQNRMGYXLMV/p/4696938.html
Copyright © 2020-2023  润新知