題目大意:給出乙個有n個數字(-1000..1000,n<=10^5)的環狀序列,讓你求乙個和最大的連續子串行。這個連續子串行的長度小於等於k。
分析:因為序列是環狀的,所以可以在序列後面複製一段(或者複製前k個數字)。如果用s[i]來表示複製過後的序列的前i個數的和,那麼任意乙個子串行[i..j]的和就等於s[j]-s[i-1]。對於每乙個j,用s[j]減去最小的乙個s[i](i>=j-k+1)就可以得到以j為終點長度不大於k的和最大的序列了。將原問題轉化為這樣乙個問題後,就可以用單調佇列解決了。
單調佇列即保持佇列中的元素單調遞增(或遞減)的這樣乙個佇列,可以從兩頭刪除,只能從隊尾插入。單調佇列的具體作用在於,由於保持佇列中的元素滿足單調性,對於上述問題中的每個j,可以用o(1)的時間找到對應的s[i]。(保持佇列中的元素單調增的話,隊首元素便是所要的元素了)。
維護方法:對於每個j,我們插入s[j-1](為什麼不是s[j]? 佇列裡面維護的是區間開始的下標,j是區間結束的下標),插入時從隊尾插入。為了保證佇列的單調性,我們從隊尾開始刪除元素,直到隊尾元素比當前需要插入的元素優(本題中是值比待插入元素小,位置比待插入元素靠前,不過後面這乙個條件可以不考慮),就將當前元素插入到隊尾。之所以可以將之前的佇列尾部元素全部刪除,是因為它們已經不可能成為最優的元素了,因為當前要插入的元素位置比它們靠前,值比它們小。我們要找的,是滿足(i>=j-k+1)的i中最小的s[i],位置越大越可能成為後面的j的最優s[i]。
在插入元素後,從隊首開始,將不符合限制條件(i>=j-k+1)的元素全部刪除,此時佇列一定不為空。(因為剛剛插入了乙個一定符合條件的元素)
c 雙端佇列應用 單調佇列
一道經典題目 講到單調佇列必定會講的乙個題目 滑動視窗 講單調佇列前先來乙個需要用到的資料結構 雙端佇列 deque 也可以用陣列進行模擬 我們需要用到的函式有這些 因為我只學我要用到的0.0 建立 deque int que 隊列為空 que.empty 佇列清零 que.clear 隊尾元素 q...
單調棧,單調佇列
大多數借鑑了 單調佇列是什麼呢?可以直接從問題開始來展開。poj 2823 給定乙個數列,從左至右輸出每個長度為m的數列段內的最小數和最大數。數列長度 n 106,m n 我們知道,解法 在暴力列舉的過程中,有乙個地方是重複比較了,就是在找當前的f i 的時候,i的前面其它m 1個數在算f i 1 ...
單調棧 單調佇列
單調棧 單調佇列是在棧和佇列的基礎上加上單調結構的資料結構。如果乙個元素入棧或入隊,他會檢查之前的元素,如果之前的元素不可能是答案的解,那麼就彈出元素,使得當前元素入棧或入隊。leetcode 239 滑動視窗最大值 此題是單調佇列,每次遇到乙個元素,一直從隊尾彈出,直到隊尾元素大於該元素為止。還需...