括号涂色题解(区间DP)

题目:

Petya遇到了一个关于括号序列的问题: 给定一个字符串S,它代表着正确的括号序列,即(“(”)与 (“)”)是匹配的。例如:“(())()” 和 “()”是正确的,“)()”与“(()”则不是正确的。 在正确的括号序列中,一个左边的括号一定是匹配一个右边的括号(反之亦然)。例如,在下图中,第 3 个括号匹配第 6 个括号,第 4 个括号匹配第 5 个括号。
在这里插入图片描述

现在你需要对一个正确的括号序列做涂色操作,严格满足以下三个条件:

1、每个括号要么不涂色,要么涂红色,要么涂蓝色。

2、一对匹配的括号需要且只能将其中一个涂色。

3、相邻的括号不能涂上同一种颜色(但是可以都不涂颜色)。

求:给整个括号序列涂上颜色的方案数,答案可能比较大,对 1000000007 取模。

输入1:

(())

输出1:

12

输入2:

(()())

输出2:

40

输入3:

()

输出3:

4

题解:

首先由于是括号,我们需要知道它的左括号下标及右括号下标,存入数组方便后面用,方法是用栈,详细见代码:

void p() {
   
	for(int i = 0;i < n; i++) {
   
		if(a[i] == '(') {
   
			s.push(i);//右括号输入进去
		}
		else{
   
			b[i] = s.top();//遇到对应左括号弹出,再对下标保存
			b[s.top()] = i;
			s.pop();
		}
	}	
	return;
}

首先这道题的状态很不一样,令dp[i][j][k][l]为i括号取k种类颜色,和j括号取l种类颜色的方案总数。dp[i][j][k][l]应等于:
1.i+1==j(i括号与j括号相邻)
取法为一个无色一个颜色二选一

dp[i][j][1][0] = 1;
dp[i][j][0][1] = 1;
dp[i][j][2][0] = 1;
dp[i][j][0][2] = 1;

2.若b[i] == j(当i括号与j括号对应时):
首先求得元区间dp[i + 1][j - 1][k][l]的方案数, 用来求一个无色,一个随便取方式比如:dp[i][j][0][1],再加上dp[i + 1][j - 1][k][l] (注意l不能为1,因为若为1,则j-1号位为一号颜色,而j号位又是一号颜色所以相邻两个重复,舍去),其它三个完全同理思考,见代码:

if(j != 1) {
   
	dp[qi][zhong][0][1] += dp[qi + 1][zhong - 1][i][j];
	dp[qi][zhong][0][1] %= mod
  • 4
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值