首页 > 其他分享 >括号匹配序列计数问题

括号匹配序列计数问题

时间:2023-05-01 09:44:59浏览次数:45  
标签:匹配 定义 括号 序列 计数问题 dp matrix

题意

一个长度为 \(n\) 且符合规范的括号序列,其有些位置已经确定了,有些位置尚未确定,求这样的括号序列一共有多少个。要求复杂度为 \(O(n^3)\)

分析

由题意可知,我们可以这样定义括号匹配序列:

  • 空序列是括号匹配序列。
  • 如果 S 是括号匹配序列,那么 \((S)\) 也是括号匹配序列。
  • 如果 A 是括号匹配序列,B 是括号匹配序列,那么 AB 也是括号匹配序列。

这样的定义似乎很正确,但对于我们的计数却有不利影响,原因如下述。
首先定义状态 \(dp[l][r]\) 为区间 \([l,r]\) 中括号匹配序列的数量,转移如下:

\[\left\{ \begin{matrix} dp[l][r] += \sum_{k = l}^r dp[l][k] * dp[k + 1][r]\\ dp[l][r] += dp[l + 1][r - 1] (s[l] == '(' \&\& s[r] == ')') \end{matrix} \right. \]

乍一看还挺正确的,其实不然。
比如对于这种情况:\(()()()\)。可以这样断开:\(()\_()()\)。也可以这样断开:\(()()\_()\)。然而这两种断开方式对应的括号匹配序列是一样的,因此就重算了。思考去重的方法,多少又有点无从下手,难道没有办法了吗?
思考一下刚才的dp对应的文法:

\[括号匹配序列定义1和2:S -> (S) | () \]

\[括号匹配序列定义3:S -> SS \]

可见,\(S\) 存在两种对应关系,这称作文法的二义性。这就导致我们算重复了。于是,切入点就变为如何设计文法,使其没有二义性。

比如下面的这种设计:

\[S -> A|B \]

\[定义1和定义2:A -> ()|(A)|(B) \]

\[定义3:B -> AB|AA \]

可见,新增了 \(A\) 和 \(B\) 两种情况,使得不存在 \(A\) 或 \(B\) 对应两种对应关系,这就消除了文法的二义性。只需要对 \(A\) \(B\) 这两种情况分别dp,最后将总和加起来即可。设 \(f[l][r]\) 为对 \(A\) 的 dp,\(g[l][r]\) 为对 \(B\) 的dp。转移如下:

\[\left\{ \begin{matrix} f[l][r] += f[l + 1][r - 1] + g[l + 1][r - 1](s[l] == '(' \&\& s[r] == ')')\\ g[l][r] = \sum_{k = l}^r f[l][k] * (g[k + 1][r] + f[k + 1][r]) \end{matrix} \right. \]

最后的答案就是 \(f[1][n] + g[1][n]\)。
如此,通过对文法设计进行改变,就能极大地降低算法复杂度。类似的思路在P7914 [CSP-S 2021] 括号序列也有体现。

标签:匹配,定义,括号,序列,计数问题,dp,matrix
From: https://www.cnblogs.com/CZ-9/p/17366186.html

相关文章

  • 时序预测 | MATLAB实现BO-CNN-LSTM贝叶斯优化卷积神经网络-长短期记忆网络时间序列预
    ✅作者简介:热爱科研的Matlab仿真开发者,修心和技术同步精进,matlab项目合作可私信。......
  • 剑指 Offer II 119. 最长连续序列
     分析:题目意思是数组里面能组合起来最长的连续数组然后直接sort排序,如果中间差数不是1就不再连续,count归零当nums[i]和nums[i-1]相等的时候,跳过代码:1classSolution(object):2deflongestConsecutive(self,nums):3"""4:typenums:List[......
  • 【dp的二分优化】NO300 最长递增子序列
    【dp的二分优化】300.最长递增子序列给你一个整数数组nums,找到其中最长严格递增子序列的长度。子序列是由数组派生而来的序列,删除(或不删除)数组中的元素而不改变其余元素的顺序。例如,[3,6,2,7]是数组[0,3,1,6,2,2,7]的子序列。示例1:输入:nums=[10,9,2,5,3,7,101,18]......
  • 2023-04-29:一个序列的 宽度 定义为该序列中最大元素和最小元素的差值。 给你一个整数
    2023-04-29:一个序列的宽度定义为该序列中最大元素和最小元素的差值。给你一个整数数组nums,返回nums的所有非空子序列的宽度之和由于答案可能非常大,请返回对109+7取余后的结果。子序列定义为从一个数组里删除一些(或者不删除)元素,但不改变剩下元素的顺序得到的数组......
  • 2023-04-29:一个序列的 宽度 定义为该序列中最大元素和最小元素的差值。 给你一个整数
    2023-04-29:一个序列的宽度定义为该序列中最大元素和最小元素的差值。给你一个整数数组nums,返回nums的所有非空子序列的宽度之和由于答案可能非常大,请返回对109+7取余后的结果。子序列定义为从一个数组里删除一些(或者不删除)元素,但不改变剩下元素的顺序得到的数......
  • C# 序列化操作类
    usingSystem;usingSystem.Collections.Generic;usingSystem.IO;usingSystem.Linq;usingSystem.Runtime.Serialization.Formatters.Binary;usingSystem.Text;usingSystem.Threading.Tasks;namespaceEIMS{[Serializable]publicstaticclass_Serial......
  • 将时间序列转换为分类问题
    本文将以股票交易作为示例。我们用AI模型预测股票第二天是涨还是跌。在此背景下,比较了分类算法XGBoost、随机森林和逻辑分类器。文章的另外一个重点是数据准备。我们必须如何转换数据以便模型可以处理它。在本文中,我们将遵循CRISP-DM流程模型,以便我们采用结构化方法来解决业......
  • 栈:删除最外层括号
    题目有效括号字符串为空""、"("+A+")"或A+B,其中A和B都是有效的括号字符串,+代表字符串的连接。例如,"","()","(())()"和"(()(()))"都是有效的括号字符串。如果有效字符串s非空,且不存在将其拆分为s=A+B的方法,我们称其为原语(primitive),其中A和B都是......
  • xml 序列化
    usingSystem.Text;usingSystem.Xml;usingSystem.Xml.Serialization;varp=newPerson{Id=1,Name="Furion",Items=newList<string>{"Furion","百小僧"}};varxml=XmlSerialize(p);Console.ReadKe......
  • Problem J: 括号匹配问题
    ProblemDescription在某个字符串(长度不超过100)中有左括号、右括号和大小写字母;规定(与常见的算数式子一样)任何一个左括号都从内到外与在它右边且距离最近的右括号匹配。写一个程序,找到无法匹配的左括号和右括号,输出原来字符串,并在下一行标出不能匹配的括号。不能匹配的左括号用......