Coloring Brackets[DP]

题目描述

Petya遇到了一个关于括号序列的问题: 给定一个字符串S,它代表着正确的括号序列,即(“(”)与 (“)”)是匹配的。例如:“(())()” 和 “()”是正确的,“)()”与“(()”则不是正确的。 在正确的括号序列中,一个左边的括号一定是匹配一个右边的括号(反之亦然)。例如,在下图中,第 3 个括号匹配第 6 个括号,第 4 个括号匹配第 5 个括号。
在这里插入图片描述
现在你需要对一个正确的括号序列做涂色操作,严格满足以下三个条件:
1、每个括号要么不涂色,要么涂红色,要么涂蓝色。
2、一对匹配的括号需要且只能将其中一个涂色。
3、相邻的括号不能涂上同一种颜色(但是可以都不涂颜色)。
求:给整个括号序列涂上颜色的方案数,答案可能比较大,对 1000000007 取模。

输入格式

输入的第一行包含一个字符串 s,(2 <= |s| <= 700)代表一个正确的括号序列。

输出格式

输出方案数。(对 10^9 + 7 取模)

样例#1 输入:
(())
样例#1 输出:
12
样例#2 输入:
(()())
样例#2 输出:
40
样例#3 输入:
()
样例#3 输出:
4

luogu上的网址

分析:

自认为是一道很难的DP,反正考试的的时候是崩溃的。

先抓住重点:
1、每个括号要么不涂色,要么涂红色,要么涂蓝色。
2、一对匹配的括号需要且只能将其中一个涂色。
3、相邻的括号不能涂上同一种颜色(但是可以都不涂颜色)。
在此之上进行分析。

设dp[i][j][k][p]表示i号位涂颜色k,j号位涂颜色p,假设不涂为0,蓝色为1,红色为2,所以第三,四维可以只有3个元素,第一,二维均为n个元素,不会爆空间。
初始化:

if(r - l == 1) {
   
		dp[l][r][1][0] = dp[l][r][2][0] = 1;
		dp[l][r][0][1] = dp[l][r][0][2] = 1;
		return;
}

然后分两大种情况:
第1类
l位与r位匹配,也就是l为’(’,r为’)'时是合法的。
此时就往中间搜,搜索(l + 1,r - 1)
当合法情况下:
dp[l][r][i][j] += 求和(dp[l +1][r - 1][k][p]) mod (1e9 + 7)
i,j,k,p均为一种颜色,且因为限制2,所以说必有i,j一个涂色,一个不涂;i,k如涂色则颜色不相同,j,p同理。
所以说 代码

if(m[l] == r) {
   
		dfs(l + 1,r - 1);
		for(int i = 0;i <= 2;i ++)
		for(int j = 0;j <= 2;j ++)
		for(int k = 0;k <= 2;k ++)
		for(int p = 0;p <= 2;p ++)
		if((
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值