Problem
给一个长度为$n$的序列$A$,定义子区间价值$W{[l,r]}=\sum{i = l}^{i \leq r}A_i$
要求选出$k$个互不相同的子区间,使选出的区间价值和最大。
Solution
首先,为了快速求出一段区间的和,我们预处理前缀和
然后就是一个很巧妙的技巧:
定义$Max_{(o,l,r)}$为以$o$为左端点,长度在区间$[l,r]$以内的权值和最大的连续区间。
很显然$Max_{(o,l,r)}=max(sum(t)-sum(o - 1), t∈[l,r])$
其中$sum(x) = \sum_{i = 1}^{i \leq x}A[i]$
因为固定了o点,$sum(o - 1)$一定是确定的,所以我们相当于要求$sum(t)$在区间$[l,r]$中的最大值。
不难想到用线段树维护,但是因为没有修改操作,可以直接用$RMQ$
然后就是贪心了,维护一个大根堆,每次询问堆顶元素的权值,在将它从堆中删除……
然后就愉快的$WA$成$SB$了……
分析错误原因,是我们没有考虑以$o$为左端点的区间有可能有不止一个区间可以为答案做出贡献……
所以我们在删除对顶元素时,还需要将剩余部分插入堆
假设当前堆顶的元素为$Max_{(o,l,r)}$且区间长度为$t$时,取到最大值
在删除后我们将$Max{(o,l,t - 1)}$与$Max{(o,t + 1, r)}$扔回堆中即可
Code
1 |
|