Codeforces 149D 括号染色(区间dp)

这里写图片描述

看到括号就不想做…………所以真的没做。考完看了题解,发现还是很好推的。

首先,预处理出括号匹配。这一步用栈可以很简单地完成,即:扫描字符串,遇到 ‘(’ 压入栈,遇到 ‘)’ 就弹出栈顶与之匹配,其正确性肉眼可见。

下面我们用match_[i]表示与第i个位置匹配的括号的位置(好绕)。

设f[ i ][ j ]表示[ i,j ]的染色方法数。

然后,我们一眼就能发现这是区间dp。那么对于区间[ l,r ]而言,无非是两种情况:

1.match[ l ]=r.
我们可以确定,f[ i ][ j ] 必然和 f[ i+1 ][ j-1 ]存在某种不可告人的关系。此时 f[ i ][ j ] 的不可行就暴露了,它还没法处理相邻/匹配括号之间的染色关系。所以,我们重新设置 f[ i ][ j ][ x ][ y ],表示区间[ i,j ], i 染色为 x,j 染色为 y时的方案数。我们规定,0表示无色,1表示红色,2表示蓝色。
现在可以进行状态转移了,加法原理:
f[ i ][ j ][ 1 ][ 0 ]+=f[ i +1][ j -1 ][ x ][ y ]; (x!=1,因为 i+1 与 i 相邻)
f[ i ][ j ][ 0 ][ 1 ]+=f[ i+1 ][ j -1 ][ x ][ y ]; (y!=1)
f[ i ][ j ][ 2 ][ 0 ]+=f[ i+1 ][ j -1 ][ x ][ y ]; (x!=2)
f[ i ][ j ][ 0 ][ 2 ]+=f[ i+1 ][ j -1 ][ x ][ y ]; (y!=2)
呃,f[ i ][ j ][ 1 ][ 1 ]这种不合法的就不管了,因为匹配的一对括号中只有一个能有颜色(尽管我觉得这真的很不优美)。

2.match[ l ]!= r.
那么我们取出 pair_=match[ l ] 作为中间节点,将 [ i,j ] 分割成两个匹配的部分。可以知道 f[ i ][ j ] 必然与 f[ i ][ pair_ ]和 f[ pair_+1 ][ j ] 有关。
乘法原理:
f[ i ][ j ][ x ][ y ]+= f[ i ][ pair_ ][ x ][ k ]*f[ pair_+1 ][ j ][ l ][ y ]; (k和l不能同为红or蓝)

特别地,当 l==r时,f[ x ][ y ][ 0 ][ 1 ]=f[ x ][ y ][ 0 ][ 2 ]=f[ x ][ y

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值