题解 P7914 【[CSP-S 2021] 括号序列】(区间 dp,前缀和优化)

这是一篇带着牢骚的题解(见末尾),为了纪念我支离破碎的 CSP2021。


括号串题,考场上第一眼看过去以为 * 能在满足 \(k\) 的情况下随便插入,于是设 \(f[i][j][k]\) 表示前 \(i\) 个字符、有 \(j\) 个带匹配的 (、并且末尾有 \(k\) 个连续 * 的合法串数量,随便转移一下就可以了,光速码完后发现过不了第一个样例,然后发现自己太 navie 了。

发现线性 dp 貌似不好实现,改用区间 dp 试试。

\(f[l,r]\) 表示区间 \([l,r]\) 的合法串数量,那么有一下几种情况:

  1. \(s[l]\)\(s[r]\) 分别可以是 ()\([l+1,k]\) 可以是 *,那么就由 \(f[k+1,r-1]\) 转移过来。

  2. \(s[l]\)\(s[r]\) 分别可以是 ()\([k,r-1]\) 可以是 *,那么就由 \(f[l+1,k-1]\) 转移过来。

  3. \(s[l]\)\(s[r]\) 分别可以是 ()\([l+1,r-1]\) 可以是 *,那么就由 \(f[l+1,k-1]\) 转移过来。(可以在处理上面两种时顺带转移掉)

  4. \(f[l,k]\)\(f[k+1,r]\) 转移过来。

  5. \([k+1,d-1]\) 可以是 *,由 \(f[l,k]\)\(f[d,r]\) 转移过来。

枚举 \(l\)\(r\) 需要 \(O(n^2)\),其中第 \(5\) 种的转移需要 \(O(n^2)\),复杂度是 \(O(n^4)\),显然过不了。

但仔细发现第 \(5\) 种中 \(d\) 的枚举可以用后缀和优化掉,于是变成了 \(O(n^3)\)

码完后你就会发现第 \(2\) 给样例过不了。

因为第 \(4\) 种和第 \(5\) 种转移有问题,一个例子: ()()()。此时 \(f[1,2]\cdot f[3,6]\)\(f[1,4]\cdot f[5,6]\) 两种转移实际上重复了。

怎么解决?

\(P\) 为形如 ()(A)(S)(AS)(SA) 的串,那么这种会重复转移的串就形如:\(P_1P_2P_3\ldots P_m\)(相邻的 \(P\) 中间有可能有若干 *,下同),我们可以枚举 \(P_1\),而剩下的 \(P_2P_3\ldots P_m\) 就是一个普通的合法串,这样的转移就没有重复了。

那么我们就可以额外设 \(g[l,r]\) 表示区间 \([l,r]\) 形如 \(P\) 的数量(相当于只有第 \(1,2,3\) 种转移的 \(f[l,r]\))。

过不了第一个样例的线性 dp 代码:link

100pts 的区间 dp 代码:link


最后谈一下感想吧,我本身属于那种思维能力不强的选手,考场上看到 T1T3 这种一股 cf 味的题肯定是放到后面做的。T1T3 暴力写完后去推了会 T1,发现不是单峰函数之后就直接放弃了,接下来就是漫长的刚 T2 的过程,中间无数次发现题目读错,代码删删写写,但是始终过不了第 \(2\) 个样例,最后人已经是麻木的了,最后 15min 的时候回头去看看 T1,发现机廊增加时新来的飞机停在哪个机廊是没有影响的,一个 set 的做法就立马会了,但是最终还是没打完。

考完后发现自己 T2 没过样例 \(2\) 是因为把一个地方的 s[k] 打成了 k,这么一个 zz 的错误耗掉了几乎整场考试的时间。

或许我可以说,是考场降智没让我一眼看出 T1 的性质。

或许我可以说,是一个手残让我把 T2 的 100pts 亲手变成了 0pts。

或许我可以说,我运气不好,开题的顺序不对,但凡先去刚 T1T3 都能有 200+

但这已经不重要了,重要的就是我很弱,我 cf 打的少,我不敢面对自己思维能力弱这个事实。

现在已经初三了,说早也不早,说晚也不晚。

以前你我见识自为高过世人,我今日才知自误了。以后还该立志功名,以荣耀显达为是。

posted @ 2022-02-09 16:34  Legitimity  阅读(139)  评论(0编辑  收藏  举报