单调性优化 DP
单调队列优化适用于转移窗口连续、且只需窗口最值的 DP,例如 dp[i]=a[i]+max(dp[j]),其中 i-K≤j<i。
单调队列步骤
- 队首弹出已离开窗口的下标;
- 用队首对应状态计算 dp[i];
- 从队尾弹出不可能优于当前状态的下标;
- 将 i 入队。
deque<int> q;
for(int i=1;i<=n;i++){
while(!q.empty() && q.front()<i-K) q.pop_front();
dp[i]=a[i]+dp[q.front()];
while(!q.empty() && dp[q.back()]<=dp[i]) q.pop_back();
q.push_back(i);
}
正确性与复杂度
队列下标递增,dp 值单调递减(求最大值时);被队尾删去的状态在更晚且更优的状态存在时永远不会成为答案。每个下标最多进出队一次,因此总时间 O(n)、空间 O(K)。
其他单调性
决策点最优位置随状态单调时,可用分治 DP 优化;满足四边形不等式的特定区间 DP 可用 Knuth 优化。它们均须先证明单调决策,不能仅因形式相似而套用。
整理自 XOJ《单调性优化DP》。