题目链接:https://vjudge.net/problem/CodeForces-149D

D. Coloring Brackets
time limit per test

2 seconds

memory limit per test

256 megabytes

input

standard input

output

standard output

Once Petya read a problem about a bracket sequence. He gave it much thought but didn't find a solution. Today you will face it.

You are given string s. It represents a correct bracket sequence. A correct bracket sequence is the sequence of opening ("(") and closing (")") brackets, such that it is possible to obtain a correct mathematical expression from it, inserting numbers and operators between the brackets. For example, such sequences as "(())()" and "()" are correct bracket sequences and such sequences as ")()" and "(()" are not.

In a correct bracket sequence each bracket corresponds to the matching bracket (an opening bracket corresponds to the matching closing bracket and vice versa). For example, in a bracket sequence shown of the figure below, the third bracket corresponds to the matching sixth one and the fifth bracket corresponds to the fourth one.

You are allowed to color some brackets in the bracket sequence so as all three conditions are fulfilled:

  • Each bracket is either not colored any color, or is colored red, or is colored blue.
  • For any pair of matching brackets exactly one of them is colored. In other words, for any bracket the following is true: either it or the matching bracket that corresponds to it is colored.
  • No two neighboring colored brackets have the same color.

Find the number of different ways to color the bracket sequence. The ways should meet the above-given conditions. Two ways of coloring are considered different if they differ in the color of at least one bracket. As the result can be quite large, print it modulo 1000000007 (109 + 7).

Input

The first line contains the single string s (2 ≤ |s| ≤ 700) which represents a correct bracket sequence.

Output

Print the only number — the number of ways to color the bracket sequence that meet the above given conditions modulo 1000000007(109 + 7).

Examples
input
  1. (())
output
  1. 12
input
  1. (()())
output
  1. 40
input
  1. ()
output
  1. 4
Note

Let's consider the first sample test. The bracket sequence from the sample can be colored, for example, as is shown on two figures below.

The two ways of coloring shown below are incorrect.

题解:

给出一串合法的括号,为括号上色,有如下原则:1)一对括号有且仅有一个是涂上颜色的, 2)颜色只有两种, 3)相邻的括号的颜色不允许相同(除非都没上色)。问:满足上述三个条件的上色方案有多少种?

1.由于给出的括号序列是合法的,即左括号与右括号一一对应。所以我们可以先预处理出每个左括号所对应的右括号。

2.详情请看代码注释。

写法一(人工枚举):

  1. #include <iostream>
  2. #include <cstdio>
  3. #include <cstring>
  4. #include <algorithm>
  5. #include <vector>
  6. #include <cmath>
  7. #include <queue>
  8. #include <stack>
  9. #include <map>
  10. #include <string>
  11. #include <set>
  12. using namespace std;
  13. typedef long long LL;
  14. const int INF = 2e9;
  15. const LL LNF = 9e18;
  16. const int MOD = 1e9+;
  17. const int MAXN = +;
  18.  
  19. LL dp[MAXN][MAXN][][];
  20. int top, Stack[MAXN], match[MAXN];
  21. char s[MAXN];
  22.  
  23. //区间为[l, r], isL为l-1处是否上色, isR为r+1处是否上色。
  24. LL dfs(int l, int r, bool isL, bool isR)
  25. {
  26. if(l>=r) return ; //因为是乘法,所以遇到非法位置,就返回1。要是加法就return0或者1(实际情况实际考虑)。
  27. if(dp[l][r][isL][isR]!=-) return dp[l][r][isL][isR];
  28.  
  29. LL ret = ;
  30. int k = match[l]; //找到与最左端的左括号匹配的右括号
  31.  
  32. if(!isL) //首先考虑为左括号上色。如果l-1处没有上色, 那么左括号就可以上两种颜色
  33. ret = (ret + (2LL*dfs(l+, k-, true, false)*dfs(k+, r, false, isR))%MOD)%MOD;
  34. else //否则, 左括号只能上一种颜色,与l-1处括号相对的颜色
  35. ret = (ret + (1LL*dfs(l+, k-, true, false)*dfs(k+, r, false, isR))%MOD)%MOD;
  36. if(k!=r || (k==r&&!isR) ) //其次为右括号上色。如果右括号不在右端点,或者在右端点但是r+1处没有上色,则可上两种颜色
  37. ret = (ret + (2LL*dfs(l+, k-, false, true)*dfs(k+, r, true, isR))%MOD)%MOD;
  38. else //否则,右括号在最右端且r+1处上了颜色,那么右括号只能上一种颜色。
  39. ret = (ret + (1LL*dfs(l+, k-, false, true)*dfs(k+, r, true, isR))%MOD)%MOD;
  40.  
  41. return dp[l][r][isL][isR] = ret;
  42. }
  43.  
  44. int main()
  45. {
  46. while(scanf("%s", s+)!=EOF)
  47. {
  48. int n = strlen(s+);
  49. top = ;
  50. for(int i = ; i<=n; i++) //为左括号找到匹配的右括号
  51. {
  52. if(s[i]=='(') Stack[top++] = i;
  53. else match[Stack[--top]] = i;
  54. }
  55.  
  56. memset(dp, -, sizeof(dp));
  57. dfs(, n, , );
  58. printf("%lld\n", dp[][n][][]);
  59. }
  60. }

写法二(for枚举,推荐):

  1. #include <iostream>
  2. #include <cstdio>
  3. #include <cstring>
  4. #include <algorithm>
  5. #include <vector>
  6. #include <cmath>
  7. #include <queue>
  8. #include <stack>
  9. #include <map>
  10. #include <string>
  11. #include <set>
  12. using namespace std;
  13. typedef long long LL;
  14. const int INF = 2e9;
  15. const LL LNF = 9e18;
  16. const int MOD = 1e9+;
  17. const int MAXN = +;
  18.  
  19. LL dp[MAXN][MAXN][][];
  20. int top, Stack[MAXN], match[MAXN];
  21. char s[MAXN];
  22.  
  23. //区间为[l, r],Lcol为l-1处的颜色, Rcol为r+1处的颜色,0代表没上色,1和2分别代表两种不同的颜色
  24. LL dfs(int l, int r, int Lcol, int Rcol)
  25. {
  26. if(l>=r) return ; //因为是乘法,所以遇到非法位置,就返回1。要是加法就return0或者1(实际情况实际考虑)。
  27. if(dp[l][r][Lcol][Rcol]!=-) return dp[l][r][Lcol][Rcol];
  28.  
  29. LL ret = ;
  30. int k = match[l]; //找到与最左端的左括号匹配的右括号
  31. for(int lc = ; lc<; lc++) //枚举这个括号的着色情况,并且需要去除掉非法的情况
  32. for(int rc = ; rc<; rc++)
  33. {
  34. if((lc&&rc)||(!lc&&!rc)) continue; //如果两个括号都没涂色或者都涂上颜色,非法
  35. if(lc && lc==Lcol) continue; //如果l-1处涂上了颜色,且l处也要涂上相同的颜色, 非法
  36. if(k==r && rc && rc==Rcol) continue; //如果匹配的右括号在最右端,且r+1处涂上了颜色,又尝试为
  37. //右括号涂上相同的颜色,非法。如果右括号不在最右端,那么就无需
  38. //考虑r+1处的着色情况了,因为右括号右边的括号必定没有上色。
  39. ret = (ret+(1LL*dfs(l+, k-, lc, rc)*dfs(k+, r, rc, Rcol))%MOD)%MOD; //统计合法的情况
  40. }
  41. return dp[l][r][Lcol][Rcol] = ret;
  42. }
  43.  
  44. int main()
  45. {
  46. while(scanf("%s", s+)!=EOF)
  47. {
  48. int n = strlen(s+);
  49. top = ;
  50. for(int i = ; i<=n; i++) //为左括号找到匹配的右括号
  51. {
  52. if(s[i]=='(') Stack[top++] = i;
  53. else match[Stack[--top]] = i;
  54. }
  55.  
  56. memset(dp, -, sizeof(dp));
  57. printf("%lld\n", dfs(, n, , ));
  58. }
  59. }

Codeforces Round #106 (Div. 2) D. Coloring Brackets —— 区间DP的更多相关文章

  1. Codeforces Round #106 (Div. 2) D. Coloring Brackets 区间dp

    题目链接: http://codeforces.com/problemset/problem/149/D D. Coloring Brackets time limit per test2 secon ...

  2. Codeforces Round #369 (Div. 2) C. Coloring Trees(dp)

    Coloring Trees Problem Description: ZS the Coder and Chris the Baboon has arrived at Udayland! They ...

  3. Codeforces Round #369 (Div. 2) C. Coloring Trees (DP)

    C. Coloring Trees time limit per test 2 seconds memory limit per test 256 megabytes input standard i ...

  4. Codeforces Round #369 (Div. 2) C. Coloring Trees(简单dp)

    题目:https://codeforces.com/problemset/problem/711/C 题意:给你n,m,k,代表n个数的序列,有m种颜色可以涂,0代表未涂颜色,其他代表已经涂好了,连着 ...

  5. Codeforces Round #336 (Div. 2) D. Zuma(区间DP)

    题目链接:https://codeforces.com/contest/608/problem/D 题意:给出n个宝石的颜色ci,现在有一个操作,就是子串的颜色是回文串的区间可以通过一次操作消去,问最 ...

  6. Codeforces Round #367 (Div. 2) C. Hard problem(DP)

    Hard problem 题目链接: http://codeforces.com/contest/706/problem/C Description Vasiliy is fond of solvin ...

  7. codeforces 149D Coloring Brackets (区间DP + dfs)

    题目链接: codeforces 149D Coloring Brackets 题目描述: 给一个合法的括号串,然后问这串括号有多少种涂色方案,当然啦!涂色是有限制的. 1,每个括号只有三种选择:涂红 ...

  8. CF149D. Coloring Brackets[区间DP !]

    题意:给括号匹配涂色,红色蓝色或不涂,要求见原题,求方案数 区间DP 用栈先处理匹配 f[i][j][0/1/2][0/1/2]表示i到ji涂色和j涂色的方案数 l和r匹配的话,转移到(l+1,r-1 ...

  9. codeforce 149D Coloring Brackets 区间DP

    题目链接:http://codeforces.com/problemset/problem/149/D 继续区间DP啊.... 思路: 定义dp[l][r][c1][c2]表示对于区间(l,r)来说, ...

随机推荐

  1. Wiley出版 SQL Server 2005宝典

    原文发布时间为:2008-07-30 -- 来源于本人的百度文章 [由搬家工具导入] Wiley出版 SQL Server 2005宝典 迅雷专用高速下载    thunder://QUFmdHA6L ...

  2. laravel 操作数据库

    建立student控制器,控制器代码 namespace App\Http\Controllers; use Illuminate\Support\Facades\DB; class StudentC ...

  3. WEB学习-HTML的骨架

    HTML的标准骨架 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://w ...

  4. Jmeter中处理json

    我们在做http接口测试的时候,返回的数据都是json串,Jmeter中本身是不支持直接处理json串的,如果要获取到返回结果中指定的值,必须要要通过正则表达式来获取到,正则表达式比较麻烦,写错了就获 ...

  5. 【WEB基础】HTML & CSS 基础入门(6)超链接

    超链接--文字链接 超链接[hyperlink]是网页中最为常见的元素之一,我们几乎可以在所有的网站页面中找到超链接.每个网站都不止一个页面,这些页面就是利用超链接进行串接.超链接帮我们实现了网页与网 ...

  6. codevs——2693 上学路线(施工)

    2693 上学路线(施工)  时间限制: 2 s  空间限制: 16000 KB  题目等级 : 黄金 Gold 题解       题目描述 Description 问题描述 你所在的城市街道好像一个 ...

  7. codevs 2964公共素数因数

    2964 公共素数因数  时间限制: 1 s  空间限制: 32000 KB  题目等级 : 白银 Silver 题解       题目描述 Description 小单同学刚学习了一个数分解成几个素 ...

  8. All you need to know about SYN floods

    http://blog.dubbelboer.com/ Date: 09 Apr 2012Author: Erik Dubbelboer SYN cookies So one day I notice ...

  9. react 起手式

    http://blog.csdn.net/zhouzhiande/article/details/52349344 http://blog.csdn.net/zhouzhiande/article/d ...

  10. 【spring boot jpa】hql语句报错 :antlr.NoViableAltException: unexpected token: roleName

    使用场景:在spring data jpa下使用@Query("hql语句") 然后在项目启动的时候报错 hql语句报错:antlr.NoViableAltException: u ...