1.適用情況
需要快速求出區間最大/最小值的情況(常用於dp優化)/有單調的題
2.原理/思路
每次有元素進隊時,找到合適的隊尾接上,保證佇列單調性。(刪除後面不必要的一段)同時,維護可用區間,及時去頭。
3.性質
一般,在動態規劃的過程中,單調佇列中每個元素一般儲存的是兩個值:
1.在原數列中的位置(下標)
2.他在動態規劃中的狀態值(而單調佇列則保證這兩個值同時單調)
4.模板題
參考部落格
有n個數(n<=100000) ,在連續m(m<=n)個數里至少要有乙個數被選擇,求選出來數的最小總和。
輸入第一行兩個整數 n,m
接下來n行 wi(wi<=100) 表示第i個數 。
輸出乙個整數,最小總和 。
sample input
5 3125
62sample output
思路分析
狀態列舉到i,當m=4時,需要在i-3到i-1中找到最小的f[j],那麼列舉到i+1時,需要在i-2到i中找到最小的f[j]。要尋找最小值的區間向後移動一位,也就是f[i-m+1]的值被拋棄,f[i-1]的值被加入。這裡可以用單調佇列處理,f[i-1]是插隊的資料。f[i-1]有資格插隊是因為它更優且更靠近i,比它更差的數將被它取代,保留那些資料沒有任何好處。而那些已經不再維護區間之外的就不必再對其進行維護,出隊即可。
#include
using
namespace std;
const
int n=
100000
;int n,m,head=
1,tail=
0,ans=
2147483647
;int a[n+1]
,f[n+1]
,que[n+1]
;int
main()
for(
int i=n;i>n-m;i--
)//求出答案
ans=
min(ans,f[i]);
printf
("%d\n"
,ans)
;return0;
}
5.序列_題解
問題描述
作為一名火星人,你為了占領地球,需要想方設法使地球人失去信心。現在你獲得了一項能力,控制今後n天的天氣溫度,對於第i天,你能將溫度控制在[ai,bi]中任意乙個數字,你的目的是使其中某段時間,溫度持續不下降,趁此來攻擊地球。現在問你最多可以使連續的多少天滿足溫度不下降。
輸入第一行給出乙個整數n,表示你能控制的天數。
接下來n行,第i行給出2個整數ai,bi,表示你能控制的天氣範圍。保證ai<=bi。
輸出輸出乙個整數,表示答案。
sample input
41 3
2 41 1
3 4sample input
資料範圍
對於20%的資料 3<=n<=10;
對於40%的資料 3<=n<=3000;
對於60%的資料 3<=n<=100000;
對於100%的資料 3<=n<=1000000,1<=ai,bi<=100000。
思路分析
由溫度要不嚴格遞增想到單調佇列。
#include
using
namespace std;
int n,a[
1000010
],b[
1000010
],q[
1000010
],head=
1,tail=
1,ans;
inline
intread()
return x;
}int
main()
ans=
max(ans,r-i);}
printf
("%d\n"
,ans)
;return0;
}
單調佇列優化DP複習篇
當我們用單調佇列優化dp的時候,目前所做的題目都是可以提煉成滑動視窗的形式。然後我們需要考慮一些細節。1,滑動視窗的端點上我們能不能取到。2,對於單調佇列我們維護的東西是什麼?有些單調佇列是自然呈上公升趨勢的。我們單調佇列一般維護的都是序列值。3,我們在dp的過程中是需要先更新值還是先滑動後再更新。...
演算法整理 複習 佇列 單調佇列 雙端佇列
這裡說一下,佇列中全部是元素從隊尾進 rear 隊頭出 head 左開右閉區間,即 rear 所指的位置是包含在佇列中的,head 所指的位置不在佇列中,所以 rear head 時隊列為空。我也分不太清應該是從隊尾進還是隊頭進比較合適,但是也不是什麼大問題,畢竟只是個變數名的問題,封裝好後並不會有...
單調棧,單調佇列
大多數借鑑了 單調佇列是什麼呢?可以直接從問題開始來展開。poj 2823 給定乙個數列,從左至右輸出每個長度為m的數列段內的最小數和最大數。數列長度 n 106,m n 我們知道,解法 在暴力列舉的過程中,有乙個地方是重複比較了,就是在找當前的f i 的時候,i的前面其它m 1個數在算f i 1 ...