Question 1. 「JOISC 2018 Day 4」糖
给定一个长度为 \(N\) 的非负整数序列 \(A\),我们称 \(S\) 是 \(A\) 的独立集仅当 \(S\) 满足如下条件:
- \(S\) 的所有元素在 \([1,N]\) 之间。
- 不存在正整数 \(x\),使得 \(x,x+1\) 都在 \(S\) 中。
- 记 \(V(S)\) 表示 \(S\) 中所有元素 \(x\) 的 \(A_x\) 的和。
已知 \(S\) 的大小最大为 \(K = \Big\lceil{\dfrac{N}{2}}\Big\rceil\),那么对于 \([1,K]\) 内的所有 \(i\) 求 \(|S| = i\) 时 \(V(S)\) 的最大值。
\(N\leq 2\times 10^5, A_i\leq 10^9\)
考虑暴力,有一个很显然的 DP 做法,就是 \(f_{i,j}\) 表示前 \(i\) 个元素中选择了 \(j\) 个时 \(V(S)\) 的最大值,时间复杂度为 \(\mathcal{O}(N^2)\)。
但是这个 DP 做法非常难以优化,我们考虑换一种做法——反悔贪心。
假设选择了 \(A_x\),将 \(A_{x-1}, A_x, A_{x+1}\) 从中剔除,并将 \(A_{x-1} + A_{x+1} - A_x\) 加入到原先 \(x\) 的位置当中。如果接下来选中了这个元素,等价于把 \(A_x\) 从选择中踢出,然后将 \(A_{x-1}, A_{x+1}\) 加入到选择中来,按照这个步骤,每次找出当前的最大值即可,时间复杂度为 \(\mathcal{O}(N^2)\)。
这个做法就有非常大的优化空间,考虑使用 STL 快速维护当前的序列局面即可,时间复杂度降为 \(\mathcal{O}(N\log_2 N)\),可以通过。