染色有三个条件:

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

首先可以根据给出的括号序列计算出括号的配对情况,具体来说就是第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)
 #include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm> using namespace std; typedef long long LL; const int maxn = + ; const LL M = 1000000007LL;
LL d[maxn][maxn][][]; char s[maxn]; int R[maxn], S[maxn]; LL DP(int l, int r, int c1, int c2)
{
if(l > r) return 1LL;
LL& ans = d[l][r][c1][c2];
if(ans >= ) return ans;
ans = ; int k = R[l];
for(int c = ; c <= ; c++)
{
if(k < r || c != c2) //color right
ans = (ans + DP(l + , k - , , c) * DP(k + , r, c, c2)) % M;
if(c != c1) //color left
ans = (ans + DP(l + , k - , c, ) * DP(k + , r, , c2)) % M;
} return ans;
} int main()
{
scanf("%s", s);
int n = strlen(s); int top = ;
for(int i = ; i < n; i++)
{
if(s[i] == '(') S[top++] = i;
else R[S[--top]] = i;
} memset(d, -, sizeof(d));
printf("%I64d\n", DP(, n - , , )); return ;
}

代码君

CodeForces 149D 区间DP Coloring Brackets的更多相关文章

  1. CodeForces 512B(区间dp)

    D - Fox And Jumping Time Limit:2000MS     Memory Limit:262144KB     64bit IO Format:%I64d & %I64 ...

  2. codeforces 1140D(区间dp/思维题)

    D. Minimum Triangulation time limit per test 2 seconds memory limit per test 256 megabytes input sta ...

  3. Timetable CodeForces - 946D (区间dp)

    大意: n天, 每天m小时, 给定课程表, 每天的上课时间为第一个1到最后一个1, 一共可以逃k次课, 求最少上课时间. 每天显然是独立的, 对每天区间dp出逃$x$次课的最大减少时间, 再对$n$天 ...

  4. Codeforces 1114D(区间DP)

    题面 传送门 分析 法1(区间DP): 首先,我们可以把连续的相等区间缩成一个数,用unique来实现,不影响结果 {1,2,2,3,3,3,5,3,4}->{1,2,3,5,3,4} 先从一个 ...

  5. CodeForces - 1107E 区间DP

    和紫书上的Blocks UVA - 10559几乎是同一道题,只不过是得分计算不同 不过看了半天紫书上的题才会的,当时理解不够深刻啊 不过这是一道很好区间DP题 细节看代码 #include<c ...

  6. Zuma CodeForces - 607B (区间DP)

    大意: 给定字符串, 每次删除一个回文子串, 求最少多少次删完. #include <iostream> #include <cstdio> #define REP(i,a,n ...

  7. Recovering BST CodeForces - 1025D (区间dp, gcd)

    大意: 给定$n$个数, 任意两个$gcd>1$的数间可以连边, 求是否能构造一棵BST. 数据范围比较大, 刚开始写的$O(n^3\omega(1e9))$竟然T了..优化到$O(n^3)$才 ...

  8. Codeforces 940 区间DP单调队列优化

    A #include <bits/stdc++.h> #define PI acos(-1.0) #define mem(a,b) memset((a),b,sizeof(a)) #def ...

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

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

随机推荐

  1. compile and link

    1. C 中 头文件的作用? 2. difference between *.a and *.so? 3. object file and executable file 4. search path ...

  2. JAVA常用知识总结(七)——Spring

    如果一个接口有2个不同的实现, 如何Autowire某一个指定的实现? 1.通过增加@Qualifier(实现类的名字): @Autowired @Qualifier("GirlStuden ...

  3. phpstorm类似sublime ctrl + alt +down多光标下移

    http://blog.jetbrains.com/phpstorm/2014/03/working-with-multiple-selection-in-phpstorm-8-eap/ 评论有一条回 ...

  4. react中的context的基础用法

    context提供了一种数据共享的机制,里面有两个关键概念——provider,consumer,下面做一些key features描述. 参考网址:https://react.docschina.o ...

  5. 使用position属性的心得

    1.使用position中的absolute要与relative配套使用,如果不使用relative时默认absolute会用整个视窗作为参照物:如果relative放在absolute的父级标签上, ...

  6. JMeter3.2入门使用教程

    JMeter3.2入门使用教程 背景说明 1.1. 背景简介 JMeter是Apache软件基金会下的一个开源项目,纯java开发的应用工具,可以作为进行负载和压力测试的工具来使用.从最开始时被设计成 ...

  7. C语言中的二级指针(双指针)

    原创作品,转载请标明出处http://blog.csdn.net/yming0221/article/details/7220688 C语言更多查看 C语言使用注意事项(一) C语言使用注意事项(二) ...

  8. gvim -- 跳转命令,查找格式,正则

    1.跳转命令 ‘w'单词前进,'b'单词后退,'e'单词前进,‘ge’单词后退,存在单词词首词尾区别,'W''B''E''gE'将不以单词区分,以空格区分 ‘$’行尾,'^'非空白行首,'0'行首 ‘ ...

  9. Servlet和JSP之标签文件学习

    在上一篇文章中介绍了自定义标签的用法,接下来介绍标签文件的用法啦. tag file指令 tag file简介 用tag file的方式,无需编写标签处理类和标签库描述文件,也可以自定义标签.tag ...

  10. Servlet和JSP之有关Servlet和JSP的梳理(一)

    大二第一学期的时候有学JSP的课,但是因为在开学之前做过JSP的小项目,所以一个学期的课也没听,直到期末考试成绩出来了,才回想JSP的内容还有多少记得,没想到模模糊糊也记不起多少,赶紧回头学回来.接下 ...