這段話**:
初談這個話題,相信許多人會有一種似有所悟,但又不敢確定的感覺。沒錯,這正是因為其中「單調」一詞的存在,所謂單調是什麼,學過函式的people都知道單調函式或者函式的單調性,直白一點說單調就是一直增或一直減。例如:1,3,5,9就是乙個單調增數列,數列中不存在後乙個數比前乙個數小的現象。那麼同樣,在這裡談到的話題也有類似特點。
先說一下單調佇列吧! 單調佇列,就是乙個符合單調性質的佇列,它同時具有單調的性質以及佇列的性質。他在程式設計中使用頻率不高,但卻占有至關重要的地位。它的作用很簡單,就是為了維護一組單調資料,讓我們在執行的過程中能夠快速尋求前k個或後k個中最大或最小的值。 至於單調棧,相信看完上面的敘述後,都會有乙個大概的理解,單調棧就是乙個符合單調性質的棧它同時具有單調的性質以及棧的性質。在作用方面兩者是相同的,差別僅是在程式設計過程中所維護的陣列的方式不同。
下面我會舉個簡單的列子來解釋單調佇列及單調棧。
例題:有一組資料1,5,9,4,7,8,6,他們會依此輸入,同時,在某一時刻會讓你求出後n個數中的最大值。
根據題意,我們可以得出這樣乙個結論,若後乙個數大於前乙個數,則結果必定不會是前乙個數(比如現在輸入了1,5,由於1<5,所以無論是後幾個數中的最大值均不會為1),因此,我們只需維護乙個單調遞減的陣列便可快速求得所需值。(陣列變化如下:輸入——1,陣列——1;輸入——5,由於5>1刪去1添入5,陣列——5;輸入——9,由於9>5刪去5添入9,陣列——9;輸入——4,由於4<9直接添入,陣列——9,4;輸入——7,由於7>4同時7<9因此刪去4添入7,陣列——9,7;輸入——8,由於8>4同時8<9因此刪去7添入8,陣列——9,8;輸入——6,由於6<8直接添入,陣列——9,8,6。)總的來說,它的本質就是當你在插入乙個值時,應將在他之前存入的所有小於他的數值剔除,再將他存入陣列中。
本人的理解:
假設需要尋找移動視窗中的最小值,如果這時候資料中進入了乙個比佇列末尾的值還要小的元素,由於這個值的位置(資料流中的位置)靠後,而且比佇列中的最後乙個元素還要小,那麼佇列中的最後乙個元素就沒有存在的必要了(因為這時候的視窗中無論如何都選不到它),之後在和佇列中的前乙個元素相比,直到遇到比它還小的值,這時候把這個元素插入。(注意:佇列中的每個元素需要儲存兩個資訊:乙個是元素的值,另乙個是元素在資料流中的位置,位置資訊是用來判斷是否該元素已經離開視窗範圍)。
//**壓著時間過了,應該還有需要優化的地方
#include #include #include #include using namespace std;
const int maxn = 1e+6 + 100;
typedef pairnode;
dequemaxque, minque;
int n, k, num[maxn];
void workmax()
printf("%d", maxque.front().second);
for (int i = k; i < n; i++) }
void workmin()
printf("%d", minque.front().second);
for (int i = k; i < n; i++) }
int main()
POJ 2823單調佇列
g tle了,c 5329ms險過。用g 交了幾遍,總覺得沒錯,也沒改就反覆交了,傻裡傻氣的。再在網路上找了一 g ce後c 過了,就也試著用c 交自己的 了,過了。要不咱研究研究g 和c 好了 以上全是廢話!include using namespace std const int nn 1000...
poj 2823 單調佇列
題目大意 給定一行數,共n個。有乙個長度為k的視窗從左向右滑動,視窗中始終有k個數字,視窗每次滑動乙個數字。求各個時刻視窗中的最大值和最小值。題目分析 單調佇列 棧中存放的一般為序列元素的索引 可能還有其他更多資訊 且每次新元素和隊尾 棧頂元素比較,若滿足單調性質,則入隊 入棧 否則,不斷彈出隊尾 ...
初談單調佇列 POJ 2823
前幾天做過這題.當時使用線段樹做的.要跑9500ms才能過.今天看了下單調佇列.以為很難.但理解一下.發現單調佇列其實很簡單.單調佇列是從數列前掃到數列後.維護乙個最值或者乙個所需的最優解之類的.每次的最優解都是在佇列的頭.所以要一直維護佇列.使其從頭到尾都是單調的.要能保證如果當前頭要出去了.後面...