單調隊列優化DP(超詳細!!!)

1、概念

一、單調隊列定義:   

其實單調隊列就是一種隊列內的元素有單調性(單調遞增或者單調遞減)的隊列,答案(也就是最優解)就存在隊首,而隊尾則是最後進隊的元素。由於其單調性因此常常會被用來維護區間最值或者下降DP的維數已達到降維來減小空間及時間的目的。數組

單調隊列的通常應用:     優化

  1. 維護區間最值     
  2. 優化DP

【例一】求m區間內的最小值(洛谷 P1440)spa

題目描述 調試

一個含有n項的數列(n<=2000000),求出每一項前的m個數到它這個區間內的最小值。若前面的數不足m項則從第1個數開始,若前面沒有數則輸出0。 blog

輸入格式 隊列

第一行兩個數n,m。 第二行,n個正整數,爲所給定的數列。 效率

輸出格式 容器

n行,第i行的一個數ai,爲所求序列中第i個數前m個數的最小值。 im

輸入 img

6 2

7 8 1 4 3 2

輸出

0 7 7 1 1 3


 思路:

一、暴力枚舉以i-1爲結尾的前m個數。時間O(n*m),T T T.

二、rmq求解O(nlog n) 貌似會T

三、線段樹求解 O(nlog n) 當n=1e7時也超時,空間,代碼量大 須要更優的O(n)的解法處理。

四、單調隊列來了 由於每個答案只與當前下標的前m個有關,因此能夠用單調隊列維護前m個的最小值,   

考慮如何實現該維護的過程??   

顯然當前下標X的m個之前的元素(即下標小於X-M+1的元素)確定對答案沒有貢獻,因此能夠將其從單調隊列中刪除。   

對於兩個元素A,B,下標分別爲a,b,若是有A>=B&&a<b那麼B留在隊列裏確定優於A,所以能夠將A刪除。    

維護隊首:若是隊首已是當前元素的m個以前,將head++,彈出隊首元素   

維護隊尾:比較q[tail]與當前元素的大小,若當前元素更優tail--,彈出隊尾元素,直到能夠知足隊列單調性後加入當前元素。   

考慮單調隊列的時間複雜度:因爲每個元素只會進隊和出隊一次,因此爲O(N)。   

通常建議用數組模擬單調隊列進行操做,而不用系統自帶的容器,由於系統自帶容器不易調試且可能有爆空間的危險。


 【 例 2】修剪草坪(信息學奧賽一本通 1599)

【題目描述】

在一年前贏得了小鎮的最佳草坪比賽後,FJ 變得很懶,再也沒有修剪過草坪。如今,新一輪的最佳草坪比賽又開始了,FJ 但願可以再次奪冠。 然而,FJ 的草坪很是髒亂,所以,FJ 只可以讓他的奶牛來完成這項工做。FJ 有 N 只排成一排的奶牛,編號爲 1 到 N。每隻奶牛的效率是不一樣的,奶牛 i的效率爲 Ei 。 靠近的奶牛們很熟悉,若是 FJ 安排超過 K 只連續的奶牛,那麼這些奶牛就會罷工去開派對。所以,如今 FJ 須要你的幫助,計算 FJ 能夠獲得的最大效率,而且該方案中沒有連續的超過 K 只奶牛。

【輸入】

第一行:空格隔開的兩個整數 N和 K; 第二到 N+1 行:第 i+1 行有一個整數 Ei 。

【輸出】

一行一個值,表示 FJ 能夠獲得的最大的效率值。

【輸入樣例】

5 2

1

2

3

4

5

【輸出樣例】

12


sol:

設 dp[i][0] 表示以 i 結尾而且 i 不選所得的最大效率值

dp[i][1]表示以 i 結尾而且 i 要選所得的最大效率值

S[i]表示前綴和

轉移方程爲:

dp[i][0]=max(dp[i-1][0],dp[i-1][1])

dp[i][1]=max(dp[x][0]+S[i]-S[x]);(i-m≤x<i)

能夠變形爲dp[i][1]=max(dp[x][0]-S[x])+S[i];(i-m≤x<i)

所以dp[i][1]能夠用單調隊列優化,維護隊首爲dp[i][0]-S[i]最大的單調隊列

相關文章
相關標籤/搜索