單調棧 佇列總結

2021-09-25 10:40:03 字數 2497 閱讀 6997

51nod-1102 面積最大的矩形

有乙個正整數的陣列,化為直方圖,求此直方圖包含的最大矩形面積。

法一:以每個柱子為高,預處理出每個點能夠向兩邊延伸的距離,左找到第乙個比當前點高度小的下標記為i,向右找到第乙個比當前點高度小的下標記為j,那麼此時以這點高度的最大值是f[i]*(j-i+1); 然後用for迴圈掃一遍求出最大值即可。解題關鍵在於求出每乙個點的邊界。

注意:處理l[1]和r[n]兩個邊界

n = read();

for(int i = 1; i <= n; ++i)

l[1] = 0;

for(int i = 2; i <= n; ++i)

} r[n] = n + 1;

for(int i = n - 1; i >= 1;--i)

} for(int i = 1; i <= n; ++i)

printf("%lld\n",ans);

法二:對於每個柱子,考慮以它作為左端點的最大右端點。

所以我們要找第乙個小於它的點。於是我們維護乙個單調遞減的棧。

以i為左端點的最大右端點就是將i彈出棧的j。所以我們在彈棧的時候處理以i為左端點的矩形對於答案的貢獻。

為了**方便,我們將a[n+1]賦成極小值,從而保證每個點都被彈出。

int main()

sta[++tp]=i;

} write(ans);

return 0;

}

2。

51nod 1158 全是1的最大子矩陣

給出1個m*n的矩陣m1,裡面的元素只有0或1,找出m1的乙個子矩陣m2,m2中的元素只有1,並且m2的面積是最大的。輸出m2的面積。

求出每個位置向右延伸,連續1的最大值,圖中的矩陣就變為

1 2 0

1 2 3

0 1 2

然後用單調棧求出每個位置,對應的行最長區間,使該位置在這區間上是最小值.就與上題一致了。

51nod 1423 最大二「貨」

給出乙個序列,求這個序列的所有子串行中最大與次大的異或值最大是多少。

列舉每個點作為次大值,用單調棧處理出左邊 / 右邊第乙個比它大的數。這樣處理相同的時候是兩邊取等或一邊取等,一邊不取等。

int main()

tp=0;

for(int i=n;i>=1;--i)

for(int i=1;i<=n;++i)

printf("%d\n",ans);

return 0;

}

51nod 1215 陣列的寬度

n個整數組成的陣列,定義子陣列a[i]…a[j]的寬度為:max(a[i]…a[j]) - min(a[i]…a[j]),求所有子陣列的寬度和.

所有子陣列的寬度和等於所有區間的最大值-所有區間的最小值。

所以我們用單調棧求出乙個點作為區間最大的次數。最小值類似。

我們從左到右維護乙個單調遞減的棧。它作為區間最大的兩端分別是它被彈出時的點(右端點),棧中它前面的點(左端點)。

51nod 1564 區間的價值

我們定義「區間的價值」為一段區間的最大值*最小值。

乙個區間左端點在l,右端點在r,那麼該區間的長度為(r-l+1)。

我們想要知道的是,對於長度為1~n的區間,最大價值的區間價值分別是多少。

有乙個定理是,對於隨機資料,從乙個數字出發,一直往後找比它小的數字,這樣能找到的數字是lg(n)級別的。

觀察本題的性質,如果長度為l的區間最大價值為x,那麼長度為l-1的區間最大價值肯定要大於等於x,因為我們可以通過右端點往左或者左端點往右,只要不彈掉最大值,答案肯定是不減的。這個記為性質1。

f[i]為長度為i的時候的最優解。

我們先用單調佇列求出對於每個數左邊右邊比它小的最近的數在**。

我們列舉最大值的位置i,再列舉最小值的位置j,然後更新這個最小值的區間.如果最小值區間中的最大值不是i,那麼肯定會在後面更新到j對應區間真正的最大值。

然後利用性質1再掃一遍更新f。**一定要注意定義單調棧時取不取等。**這裡的含義是用最小值更新,那麼相同的值也在更新的範圍內。

int main()

tp=0;

a[n+1]=-inf;

sta[++tp]=n+1;

for(int i=n;i>=1;--i)

for(int i=1;i<=n;++i)

j=i;

while(j!=n+1)

} for(int i=n;i>=1;--i)

f[i]=max(f[i],f[i+1]);

for(int i=1;i<=n;++i)

return 0;

}

單調佇列與單調棧總結

ref 單調棧解決的是以某個值為最小 最大 值的最大區間,實現方法是 求最小值 最大值 的最大區間,維護乙個遞增 遞減 的棧,當遇到乙個比棧頂小的值的時候開始彈棧,彈棧停止的位置到這個值的區間即為此值左邊的最大區間 同時,當乙個值被彈掉的時候也就意味著比它更小 更大 的值來了,也可以計算被彈掉的值得...

棧和佇列 單調佇列 單調棧

講解部落格鏈結 一 單調棧 1 什麼是單調棧?單調棧是指乙個棧內部元素具有嚴格單調性 單調遞增,單調遞減 的一種資料結構。2 單調棧的兩個性質 滿足從棧頂到棧底具有嚴格的單調性 滿足後進先出的特徵,越靠近棧底的元素越早的進棧。3 元素進棧的過程 對於當前進棧元素x 如果x 棧頂元素,x 進棧。否則 ...

單調佇列 單調棧

參考文章 單調佇列 poj 2823 給定乙個數列,從左至右輸出每個長度為m的數列段內的最小數和最大數。數列長度 n 106 m n n 106,m n n 106 m n 直接暴力求解複雜度在0 mn 可以考慮維護區間最值,單調佇列則是維護區間佇列的強大 單調佇列的定義 單調佇列實現的大致過程 1...