样例输入:
3
2 2
()
2 4
)(
2 4
()
样例输出:
1
1
2
题意:已知括号序列a是一个长度为m的合法括号序列b的子序列,求可能的序列b的数量。
分析:f[i][j][k]表示在序列b的前i位中,包含序列a的前j个字符,且左括号比右括号多k个的方案数
最后的答案显然是f[m][n][0]
更新方法:
我们每次枚举序列b中第i个字符的可能情况,以及其是否参与到与序列a的lcs序列中,所以就会有四种情况,我们分别讨论一下就行.
第一种情况:序列a的第j个字符是(,且b的第i个字符和a的第j个字符组成lcs序列,那么有f[i][j][k]=(f[i][j][k]+f[i-1][j-1][k-1])%mod,也就是说b序列的第i个字符是(,那么前i-1个字符中(数目就比)数目多k-1个,而且前一个状态的最长匹配长度是j-1
第二种情况:序列a的第j个字符是),且b的第i个字符和a的第j个字符组成lcs序列,那么有f[i][j][k]=(f[i][j][k]+f[i-1][j-1][k+1])%mod,也就是说b序列的第i个字符是),那么前i-1个字符中(数目就比)数目多k+1个,而且前一个状态的最长匹配长度是j-1
第三种情况:当前位置放(,但是a序列的第j个字符是),所以无法与a序列第j个位置进行匹配,那么就有f[i][j][k]=(f[i][j][k]+f[i-1][j][k-1])%mod,因为当前位置是(,所以前i-1个位置中(数目就比)数目多k-1个,与a序列匹配数目不变
第四种情况:当前位置放),但是a序列的第j个字符是(,所以无法与a序列第j个位置进行匹配,那么就有f[i][j][k]=(f[i][j][k]+f[i-1][j][k+1])%mod,因为当前位置是),所以前i-1个位置中(数目就比)数目多k+1个,与a序列匹配数目不变
需要注意的一点就是边界问题,在动态转移过程中不能出现用负数对数组进行索引的情况。
下面是代码:
#include
#include
#include
#include
#include