。。。顧名思義,資料是具有某方面的單調性質的(單增或單減等)。單調佇列一般是用於優化動態規劃方面問題的一種特殊資料結構,且多數情況是與定長連續子區間問題相關聯。
1.雙端佇列deque
雙端佇列是一種線性表,遵守先進先出的原則。其支援下面四種操作:
(1)從隊首刪除
(2)從隊尾刪除
(3)從隊尾插入
(4)查詢線性表中任一元素的值
2.單調佇列單調佇列是種特殊雙端佇列,其內部元素具有單調性。最常用的是最大佇列與最小佇列,其內部元素分別單增或單減。
有如下操作:
(1)插入:若新元素從隊尾插入會破壞單調性,則刪除隊尾元素,直到不在破壞單調性為止,再將其加入單調佇列尾。
(2)獲取最優(max,min)值:訪問隊首元素。
1.自願者選拔
題目大意:有一群自願者陸陸續續的來排隊,隊首的人在某些時刻才會離開,每個人有乙個int型的人品值,現在就問在當前佇列中人品最大的是多少,沒有的話輸出-1.
1.c name rp 名字為name人品為rp的人排到隊尾
2.g 隊首的人出隊
3.q 詢問當前佇列中rp最高的
分析:這個就是乙個連續區間最大值的問題。這時單調佇列裡面的人出了先後順序是單增的,其rp是單減的(head to tail)。用乙個out變數記錄目前出隊了多少人,in記錄進來了多少了,
當某次詢問時,如果out <= in時,顯然輸出-1,不然就輸出隊首的人的rp值。
因為佇列裡面做調整的時候,對首的人原位置並不是第一,所以要記錄些這個每個人的原位置。這樣就可以o(n)的解決這個問題了。
const
int maxn = 1e6 + 10;
struct node
node(char c, int rp,int pos)
}p[maxn];
int main(int argc, const
char * argv)
else
if (op[0] == 'g') else
if (op[0] == 'q')else
if (op[0] == 'e') break;}}
return
0;}
2.sliding windows
題目大意:給定n,k值和n個數字,問數列中從左到右每連續k個數的最大最小值。
分析:這又是乙個定長區間的最值問題。對於區間[l, r]和[l + 1, r + 1],當上乙個區間訪問完後,刪掉a[l]是不會對後面區間的訪問產生影響的,這時位置和值都呈現出單調性了。當訪問r時,對於隊首的元素,如果不在[l,r]範圍內的話就剔除佇列,對於尾部元素則是小於a[r]的剔除佇列。
const int maxn = 1e6 + 10;
int n, m;
struct node
node(int
pos,int value)
}p[maxn];
int a[maxn];
void get_max()
}void get_min()
}int main(int argc, const char * argv)
return
0;}
3.max sum of max-k-sub-sequence
題目大意:給出乙個迴圈數列a[1]…a[n],a[1]與a[n]相鄰。然後問數列中連續不超過k個元素的最大和是多少並列印出maxsum始末位置。
分析:這題先得變換下表達方式,a[j+1] + … + a[i] = sum[i] - sum[j],sum[i]表示a[1]到a[i]的和。對於給定的i而言,ans = max(sum[i] - sum[j]) && (i - j <= k - 1),這時sum[i]是個定值,求ans的最大等同於求sum[j]的最小值i - k <= j <= i。就相當於維護定長區間的最小值問題了,每次更新答案的時候記錄下始末位置就好了。
#include
#include
const int maxn = 1e5 + 10;
const int oo = -2099900000;
intq[maxn<<1];
ints[maxn<<1];
int nu[maxn<<1];
int n, k;
int main(int argc, const char * argv)
for (i = n + 1;i <= n + k - 1;++i)
s[i] = s[i - 1] + nu[i - n];
head = 0, tail = 0;
ans = oo;
for (i = 1;i <= n + k - 1;++i)
}if (second > n) second -= n;
printf("%d
%d%d\n", ans, first, second);
}return
0;}
單調佇列 單調棧
參考文章 單調佇列 poj 2823 給定乙個數列,從左至右輸出每個長度為m的數列段內的最小數和最大數。數列長度 n 106 m n n 106,m n n 106 m n 直接暴力求解複雜度在0 mn 可以考慮維護區間最值,單調佇列則是維護區間佇列的強大 單調佇列的定義 單調佇列實現的大致過程 1...
棧和佇列 單調佇列 單調棧
講解部落格鏈結 一 單調棧 1 什麼是單調棧?單調棧是指乙個棧內部元素具有嚴格單調性 單調遞增,單調遞減 的一種資料結構。2 單調棧的兩個性質 滿足從棧頂到棧底具有嚴格的單調性 滿足後進先出的特徵,越靠近棧底的元素越早的進棧。3 元素進棧的過程 對於當前進棧元素x 如果x 棧頂元素,x 進棧。否則 ...
單調棧 佇列學習
推薦部落格 單調棧 佇列只需滿足兩個條件即可,序列是單調的,並且符合棧和佇列的特性。實現 例如實現乙個單調遞增的棧,比如現在有一組數10,3,7,4,12。從左到右依次入棧,則如果棧為空或入棧元素值小於棧頂元素值,則入棧 否則,如果入棧則會破壞棧的單調性,則需要把比入棧元素小的元素全部出棧。單調遞減...