题意
一个括号序列被称为好的当且仅当将某一连续子段取反后是一个合法的括号序列。现在有一个带有通配符的括号序列,求有多少个好的括号序列能匹配上。
n ≤ 300 n\leq 300 n≤300。
题解
这个题是WC时yml讲到的。其实在讲课前很久就看过这题了,当时想了几天,一点不会,连多项式算法都想不到。听了题解,感觉实在很厉害,确实难想。
先判掉 n n n为奇数的情况。
定义一侧前缀和合法当且仅当它始终 ≥ 0 \geq 0 ≥0,显然一个是合法括号序列当且仅当两侧前缀和均合法。
假设翻转了 [ l , r ] [l,r] [l,r]后合法,显然有 S r = S l − 1 + S n 2 S_r=S_{l-1}+\frac{S_n}{2} Sr=Sl−1+2Sn; ∀ S i ≥ 0 , i ∈ [ 0 , l − 1 ] \forall S_i \geq 0,i \in[0,l-1] ∀Si≥0,i∈[0,l−1]; ∀ S i ≤ 2 ∗ S l − 1 , i ∈ [ l , r ] \forall S_i \leq 2*S_{l-1},i \in [l,r] ∀Si≤2∗Sl−1,i∈[l,r]; ∀ S i ≥ S n , i ∈ [ r + 1 , n ] \forall S_i \geq S_n,i \in[r+1,n] ∀Si≥Sn,i∈[r+1,n]。
一个好的序列可以分成三种情况:
- 本身就是一个合法括号序列
- 一侧不合法,一侧合法
- 两侧均不合法
第一种情况容易处理。
第二种情况,可以不用考虑第三条限制。不妨假设从左往右不合法,那么为满足第一条限制,考虑取第一次 S S S变为 − 1 -1 −1前的最大值 A A A,显然翻转时取 A A A的位置为左端点最有可能成功。令 B = S n B=S_n B=Sn,有 B ≤ 0 B\leq 0 B≤0,则右端点的值为 A + B 2 A+\frac{B}{2} A+2B,并且为满足第二条限制,会取最前面的一个,要求第一次变为 − 1 -1 −1到这个位置的数满足第二条限制。那么枚举 A A A和 B B B的值,以及第一次变为 − 1 -1 −1的位置,直接dp可以做到