发现自己对 $DP$ 优化一无所知.
Links there:BZOJ-4709
题意
有 $N$ 个贝壳,每个贝壳有颜色 $s_i$ 可以取若干段的贝壳并每次指定一个颜色 $x$ ,定义在每个选择的区间内对答案的贡献为 $x \times t[x]^2$ ,其中 $t[x]$ 为在这一段中颜色 $x$ 的出现次数
思路
先要想一个结论:
假设每次取的区间为 $[L,R]$ 那么必定有 $s_L = s_R$ ,也就是两端颜色相同.这样取一定是最优的.
如果两端颜色不一样的话 那么这一点可以归到左边或者归到右边 而且对单单这一段的答案没有影响 所以正确性显然 这样找的一定最大
那么记录 $c[i]$ 为颜色 $s_i$ 从开始出现到现在的次数 显然有转移
这样的复杂度是 $O(n^2)$ 的.
考虑优化 显然不能斜率优化 因为对于 $i<j$ , $i$ 的决策会影响到 $j$ 的决策
观察转移方程 发现如果说有 $k < j \leq i$ 假如 $k$ 的转移要比 $j$ 优秀,那么在后面的转移中 $j$ 是一定用不到的 因为平方会越来越大 因此可以对每一个颜色开一个栈 每次发现栈顶的没有下面那个转移优秀就把他弹掉.
然后你就发现你WA了
因为这么做只能保证被弹掉的不再有用 但我们求的是最大值 无法保证栈顶的一定最优秀 比如出现栈中第三个更优秀的情况.
那么我们就要从入栈时间来想 仍然假设 $k < j \leq i$ ,我们假定 $k$ 转移在 $k_1$ 优于 $i$ ,$j$ 在 $j_1$ 优于
$i$ 如果有 $k_1 < j_1$ 会发生什么呢.
仔细模拟之后我们发现 栈中第一个元素比第二个优秀,而下面还有一个更优秀的 $k_1$ 我们没把它取出来.
这就是万恶之源 因此遇到 $k_1 < j_1$ 的情况 就弹出 保证栈内元素比上一个元素更优的时间也是单调的 因此二分去找这个 “更优时间” 就行啦.
复杂度$O(nlogn)$ 可以搞过去.
Code
1 | //Keep pluggin',this is your only outlet. |