HDU2993

集训队训练的时候遇到的,真的是做不出来,在比赛过程中搜索题解了233。

题意:给 (n) 个数的数组,遍历所有长度至少为 (k) 的区间,对每个区间分别求其平均值,找出最大的平均值。

题解:先写成前缀和的形式,忽略掉“区间长度至少为k”的条件,相当于求 (frac{sum[R]-sum[L-1]}{R-L+1}) 的最大值。

变成这个形式之后,就可以看出来是个斜率优化dp了?

把每个点对 ((i,sum[i])) 画在坐标轴上,上面这个式子就是要求最大的斜率。

正常的求下凸壳的办法是单调栈,不过这里要求“区间长度至少为k”,用个双端队列做一个单调队列就很好。

具体是这样的:从单调队列中的队尾出队的点,以后也不会产生贡献,直接不用考虑他们。而这个单调队列中的元素,队尾总是最优解(最大斜率),所以到一定程度之后也可以丢弃队头,检测队头节点是否距离队尾节点的长度至少为k,若有则需要丢弃队头,把队头放在一个临时变量里面保存下来,直到新的队头与队尾的长度少于k,这样以每个点为结尾的最佳决策点就是这个临时变量中的东西(队头的前一个点)。


但是写出来之后不是WA而是TLE了,是不是太久不写了。

原文地址:https://www.cnblogs.com/KisekiPurin2019/p/12731739.html