标签:
染色有三个条件:
首先可以根据给出的括号序列计算出括号的配对情况,具体来说就是第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染这个序列的左括号还是右括号:
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\n", DP(0, n - 1, 0, 0)); 52 53 return 0; 54 }
CodeForces 149D 区间DP Coloring Brackets
标签:
原文地址:http://www.cnblogs.com/AOQNRMGYXLMV/p/4696938.html