1.蓝桥杯 括号序列(AcWing 由有题目)
https://www.acwing.com/problem/content/3423/
大意:给定一个括号序列,要求尽可能添加少的的括号,形成完全匹配的序列,问有多少种不同的添加结果?给定的序列长度<=5000。
思路:这题可以说是很难的dp了。首先得明确括号匹配的等价条件:(1)左括号和右括号数量相等,(2)任意一个前缀左括号的数量不小于右括号的数量。
具体思路如下:(1)首先对于添加括号操作是独立的可以分开进行操作。为什么呢?因为我们不会添加一对相匹配的括号,因为我们要满足添加最少括号的限制,所以添加的左括号是和原序列的右括号匹配,添加的右括号是和原序列的左括号匹配,所以左右括号添加时可以分开来看(2)对于添加左右括号的方案数也是相互独立的,因为添加总是在原序列括号的间隙中添加,显然对于在不同间隙的左右括号,不会造成本质重复的结果。对于在同一个间隙的左右括号,他们的排列方式是确定的即前面是右括号,后面是左括号,否则就会形成匹配,也不会造成“本质重复”,所以方案数符合乘法原理。
我们可以通过算左右括号的最少添加方案数,求他们的乘积就行了。
接下来就是dp求方案数了,写一个求左括号的dp函数,对于右括号的求法实际上就是把序列翻转,左右括号互换再调用一次函数。
对于求添加左括号的方案数,因为求的是本质不同的,所以相当于求被右括号分割开的每段的数量求方案数。
f[i,j]表示前i个中左括号比右括号多j个的集合,属性为方案数。
状态划分:首先根据第i个是左括号还是有括号分为两大类,对于第i个是左括号的情况显然f[i,j]=f[i-1,j-1]。
对于第i个括号是有括号f[i,j]根据添加括号的数量即添加0个,添加1个,…添加 j+1个划分为
f [i-1,j+1], f [i-1,j] ,…f[i-1,0]。
所以状态转移方程为f[i,j]=f[i-1,j+1]+f[i-1,j]+…f[i-1,0].
因为 f[i,j-1]=f[i-1,j]+…f[i-1,0]。所以f[i,j]=f[i-1,j+1]+f[i,j-1].,对于返回结果我们返回的是f[n,j]最小的j的方案数不为0的方案,因为要添加最少的括号。
对于右括号的计算同理。完毕。
总结:(1)括号匹配的等价条件(2)dp状态表示很重要。