CF913E - Logical Expression 题解
不请自来,这是 tourist 出的「hot tea」哦 %%%。
拒绝打表。我们考虑一个显然的 DP:\(dp_i\) 表示 \(i\) 被表示出来的最小字符串。转移的时候呢,由于我们需要知道被逻辑运算符连接的 $1\sim2 $ 个表达式分别需不需要加括号,我们需要知道这个表达式的最后一步的逻辑运算符的优先级和当前逻辑运算符的优先级的大小关系。于是不难想到在 DP 状态上再加一维表示最后一步逻辑运算符的优先级,分成三级,无符号和非符号是最高级。至此都非常自然吧。
然后这个 DP 显然是有后效性的。我们考虑这样一个方案:分成若干轮,每轮无后效性地用上一轮的结果来松弛本轮。而且这个一脸小清新样子,看起来不出几轮就能获得稳定状态,永远不会松弛成功。有些人就用打表了,这好吗,这不好。我使用的是卡时,卡了 \(2\mathrm s\) 大约跑了 \(5\) 次(一次的复杂度 \(\mathrm O\!\left(3^22^{16}\right)\) 带大常数),得到了正确的结果。
最后输出就可以了,\(n\leq 10000\) 是个幌子。
真就乱搞做题呗,code。
但是正解不是乱搞,毕竟是 tourist 出的题。
看到有后效性最优化 DP,我们想到抽象成最短路模型。但这个 DP 的转移是依靠两个决策同时松弛的,无法转化为图。但是如果视最短路为特殊的有后效性最优化 DP 的话,我们可以使用最短路算法的核心思想来优化一般的有后效性最优化 DP。
可见上面那个乱搞就是 Bellman-Ford。我们考虑 Dijkstra,它的核心思想是,逐步把最短路数组确定化,每轮选出未确定的中最小的,那么有结论说它已经确定了,用它来松弛其他人,进入下一轮。
我们来考虑这个东西的证明,然后来试图转化到本题这个一般有后效性最优化 DP 这个广义的最短路。每轮中选出未确定中最小的来确定,注意到一个值已经被确定了当且仅当它的最短路的上一个(在 DP 中叫做最优决策)在之前被确定并且把别人松驰过了。然后我们假设最小的没被确定,那么它的最优决策没被确定,但这个最短路这条链是通向源点的,那么终究有一个更大的被确定了,那最短路怎么可能越跑越短呢(可见边权必须为正才能 Dijkstra)。
回到这题,我们考虑每次选出未确定的 DP 值中最小的来确定。那么它确实应该被确定当且仅当它的最优决策对的两个 DP 值都已经在之前被确定了。假设不成立,那么必有后面更大的确定 DP 值作为它的间接最优决策,这是不可能的。那么这样就是对的,复杂度 \(\mathrm O\!\left(3^22^{16}\right)\),甚至不需要堆优化,因为在这个广义的图中有 \(m=\mathrm O\!\left(n^2\right)\)。
以上。