集训队训练的时候遇到的,真的是做不出来,在比赛过程中搜索题解了233。
题意:给 (n) 个数的数组,遍历所有长度至少为 (k) 的区间,对每个区间分别求其平均值,找出最大的平均值。
题解:先写成前缀和的形式,忽略掉“区间长度至少为k”的条件,相当于求 (frac{sum[R]-sum[L-1]}{R-L+1}) 的最大值。
变成这个形式之后,就可以看出来是个斜率优化dp了?
把每个点对 ((i,sum[i])) 画在坐标轴上,上面这个式子就是要求最大的斜率。
正常的求下凸壳的办法是单调栈,不过这里要求“区间长度至少为k”,用个双端队列做一个单调队列就很好。
具体是这样的:从单调队列中的队尾出队的点,以后也不会产生贡献,直接不用考虑他们。而这个单调队列中的元素,队尾总是最优解(最大斜率),所以到一定程度之后也可以丢弃队头,检测队头节点是否距离队尾节点的长度至少为k,若有则需要丢弃队头,把队头放在一个临时变量里面保存下来,直到新的队头与队尾的长度少于k,这样以每个点为结尾的最佳决策点就是这个临时变量中的东西(队头的前一个点)。
但是写出来之后不是WA而是TLE了,是不是太久不写了。