CodeForces 149D Coloring Brackets

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

-----------------------------------------------------------------------------------------------

半年前这道区间$DP$磨叽了一天不会 现在感觉是很多地方的题解没写清楚 自己多想会就好了

首先我们用$F[L][R][c1][c2]$表示从$L$到$R$这段区间左右端点颜色分别为$c1,c2$的方案数

$($颜色为$0$代表无色$)$然后用记忆化搜索求解

做的过程中要分两种情况进行讨论

$1.$若$L,R$为匹配的括号 则对区间$[L + 1,R - 1]$进行讨论

2.否则对$[L,m[L]],[m[L] + 1, R]$进行讨论$(m$为该左括号匹配的右括号位置$)$

最后对于$L + 1= R$的区间特判即可

-----------------------------------------------------------------------------------------------

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <cmath>
 4 #include <algorithm>
 5 using namespace std;
 6 const int N = 710, mod = 1e9 + 7;
 7 char s[N];
 8 long long f[N][N][3][3];
 9 bool check[3][3] = {{0, 1, 1},{1, 0, 0},{1, 0, 0}};
10 bool check2[3][3] = {{1, 1, 1},{1, 0, 1},{1, 1, 0}};
11 int m[N], st[N];
12 int n, top;
13 long long ans = 0;
14 long long dfs(int L, int R, int c1, int c2)
15 {
16     if(f[L][R][c1][c2] != -1)
17         return f[L][R][c1][c2];
18     f[L][R][c1][c2] = 0;
19     if(m[L] == R)
20     {
21         if(!check[c1][c2])
22             return 0;
23         if(L + 1 == R)
24             return f[L][R][c1][c2] = 1;
25         for(int i = 0; i < 3; ++i)
26             for(int j = 0; j < 3; ++j)
27                 if(check2[c1][i] && check2[j][c2])
28                     f[L][R][c1][c2] = (f[L][R][c1][c2] + 
29                     dfs(L + 1, R - 1, i, j)) % mod;
30     }
31     else
32     {
33         for(int i = 0; i < 3; ++i)
34             for(int j = 0; j < 3; ++j)
35             {
36                 if(check2[i][j] && check[c1][i])
37                     f[L][R][c1][c2] = (f[L][R][c1][c2] + 
38                     dfs(L, m[L], i, c1) * dfs(m[L] + 1, R, c2, j)) % mod;
39             }
40     }
41     return f[L][R][c1][c2];
42 }
43 int main()
44 {
45     scanf("%s", s + 1);
46     n = strlen(s + 1);
47     for(int i = 1; i <= n; ++i)
48         if(s[i] == '(')
49             st[top ++] = i;
50         else
51             m[st[-- top]] = i;
52     memset(f, -1, sizeof f);
53     for(int i = 0 ; i < 3; ++i)
54         for(int j = 0; j < 3; ++j)
55             ans += dfs(1, n, i, j);
56     printf("%lld\n", ans % mod);
57     return 0;
58 }

 

posted @ 2016-02-01 21:46  sagitta  阅读(150)  评论(0编辑  收藏  举报