首先看这样一个方程:f[i] = max{f[j] + s[i] - s[j + 1]}, j >= i - m 。
对于该方程,如何用单调队列优化呢?
移项之后,有 f[i] - s[i] = f[j] - s[j + 1] 。很显然,维护等式右边的值单调递减即可,每次剔除无用决策,在用当前所得决策更新所有不如其优的决策,因为那些决策如果不如当前决策优,那么他们便毫无用处了。这样每次的决策都是最优的。
然而再看这样一个方程:f[i] = min{f[j] + i - j - 1}, g[i] = min{s[i] - s[j]}, g[i] >= g[j] 。
这样的方程看上去并无单调性。然而,又可以发现两个性质:
1. f[j] - j 单调非升。显然,j 每次增大 1,而 f[j] 却不一定。
2. s[i] >= s[j] + g[j] 成立,则决策合法,而 s[i] 单调递增。
如何利用这两个性质呢?
首先对于性质 1,可以知道越靠后的决策越优。而对于性质 2,每次都可以在退队首的时候判断更靠后的决策是否可行,以及为了使 g[i] 取到最小值,在已知靠后决策不更差的情况下退队尾。这样一来,即维护了一个决策单调递增,决策代价单调非降,g 值单调非降的单调队列。这样,每次取到更新过的队头,都是最优值。
以上的两个例子无论是从单调性还是取值,都截然不同,但都是用单调队列维护。所以说考试的时候要认真分析。