树状数组优化 DP
Description
给出一个长度为 $n$ 的序列, 可以进行最多 $k$ 次区间 $+1$ 操作。
求能得到的最长 $\mathbf {LIS}$ 长度. $n \leq 10^4, k \leq 500, a_i \leq 1000$.
Samples
Input #1
1 | 3 1 |
Output #1
1 | 3 |
Solution
考虑猜个结论,所有操作的右端点必然为 $n$.
发现很好证明,因为如果对于一个端点两侧都不为空的区间执行操作后,其左端点左侧的区间 $\mathbf {LIS}$ 不变; $1$ 到其右端点这个区间的 $\mathbf {LIS}$ 将会增加或不变; 但右端点右侧区间的 $\mathbf {LIS}$ 将会减少或不变。所以结论得证。
然后就可以暴力转移,设状态 $\mathbf{DP}_{i,j}$ 表示 $\mathbf {LIS}$ 以 $i$ 位置为结尾且 $i$ 被 $j$ 个区间操作覆盖时的答案,那么我们枚举 $\mathbf{LIS}$ 的上一个元素进行转移:
复杂度是 $\Theta(n^2k^2)$ 的,可以得到 0 分的好成绩。
考虑优化,看到这个转移方程式是个三维前缀最大值,那么我们枚举 $i$ 把它变成二维。那么状态改为 $\mathbf {DP}_{j,k}$ 表示 $1 \sim i - 1$ 被不超过 $j$ 个修改区间覆盖,其 $\mathbf {LIS}$ 结尾权值不超过 $k$ 的答案。
如果直接二维树状数组维护的话是 $\Theta(nk\log n\log k)$ 的,但这还是太 naive 了。
发现状态存在当 $j$ 不变时 $\mathbf{DP}_{j,k}$ 随 $k$ 增大而单调递增,$k$ 不变时随 $j$ 增大而单调递增,那么树状数组里 $x \leq j, y \leq k$ 的最大值,一定在第 $j$ 行或第 $k$ 列取到。
那么我们建两个 $n$ 行的树状数组,分别维护行/列的 $\mathbf {DP}$ 值,按照上面所述修改更新即可,复杂度是 $\Theta (nk\log n)$ 的,在某谷也跑到了最优解。
Code
1 | /* Headers */ |