首先我们考虑最暴力的方法,仿照着 LIS 板子题设计状态:\(dp_{i,j}\) 表示考虑前 \(\max(i,j)\) 个,单减序列以 \(i\) 结尾,单增序列以 \(j\) 结尾,然后进行 \(O(1)\) 的转移。
但是这样状态数就爆炸了,如何优化状态数呢?
我们考虑进行换维。因为我们刚刚设计的是一个弱鸡的可行性 DP,很强力的“答案”这个位置上却被我们放上了 \(0/1\) 这样信息很少的东西。
那么就考虑设 \(f_i\) 表示单增序列以 \(i\) 结尾,单减序列最后一项的最大值(浅浅运用贪心的思想,反正只要能分成两个序列就行了,没必要考虑长度的话,只要是已经考虑过的位置,它们之间的相对关系并不重要)。
开始打补丁,因为一个位置也有可能是单减序列的结尾,所以考虑再设一个 \(g\)。
设 \(g_i\) 表示单减序列以 \(i\) 结尾,单增序列最后一项的最小值。那么就可以交替转移了。
转移式子在代码里面。(如果对会不会漏掉情况有疑问,可以这样想:\(f_i,g_i\) 是在考虑前 \(i\) 位时的两个最优情况,其它的情况能匹配的接下来(\(i\) 位之后)的方案,一定能是他们两个交集的子集)。