考场挂分器,送分题变成送命题。
一、状态:
令 dp[i][j]dp[i][j]dp[i][j] 表示 [i,j][i, j][i,j] 这个区间内组成超级括号序列的方案数
令 f[i][j]f[i][j]f[i][j] 表示在 dp[i][j]dp[i][j]dp[i][j] 的要求上,添加限制:方案中,括号 iii, jjj 匹配。
令 ans[i][j]ans[i][j]ans[i][j] 表示 [i,j][i, j][i,j] 这个区间能不能做到 [l,r][l, r][l,r] 全为 “*”。
令 check(l,r)=[[[s[l]=?]∨[s[l]=∗]]∧[[s[r]=?]∨[s[r]=∗]]]check (l, r) = \bigg[ \Big[ [s[l] = ?] \lor [s[l] = *] \Big] \wedge \Big[ [s[r] = ?] \lor [s[r] = *] \Big] \bigg]check(l,r)=[[[s[l]=?]∨[s[l]=∗]]∧[[s[r]=?]∨[s[r]=∗]]]
attention: 这里区间的含义和数学上是一样的,不会是空集。
二、初始化:
ansansans 即判断这个区间内是不是全是 “?” 或 “*”。 dp,fdp, fdp,f 全部设为 000。
三、状态转移:
考虑所有情况,每种情况对应一种转移。
- ()
这种情况特判即可。
dp[l][r]=f[l][r]=check(l,r)∗[l+1==r] dp[l][r] = f[l][r] = check (l, r) * [l + 1 == r] dp[l][r]=f[l][r]=check(l,r)∗[l+1==r]
- (S)
这是 s[l],s[r]s[l], s[r]s[l],s[r] 已经匹配好了,则 [l+1,r−1][l + 1, r - 1][l+1,r−1] 全为 * 就行了。
dp[l][r]=f[l][r]=ans[l+1][r−1] dp[l][r] = f[l][r] = ans[l + 1][r - 1]dp[l][r]=f[l][r]=ans[l+1][r−1]
- (SA)
我们枚举 S 的最后一个字符的位置。
即统计 [l+1,i][l + 1, i][l+1,i] 全为 *,[i+1,r−1][i + 1, r - 1][i+1,r−1] 为超级括号序列的方案数。
dp[l][r]=f[l][r]=∑i=l+1i+1≤r−1ans[l+1][i]∗dp[i+1][r−1]dp[l][r] = f[l][r] = \sum_{i = l + 1}^{i + 1 \leq r - 1} ans[l + 1][i] * dp[i + 1][r - 1]dp[l][