從一道題簡談單調佇列(乙個蒟蒻的理解)

2021-08-15 08:01:33 字數 1648 閱讀 2252

首先引入乙個問題,原**本人翻譯如下:

題目描述

給乙個大小為n

的陣列(

n≤ 10

6)。有乙個大小為k的滑動窗,從陣列的最左邊移動到最右邊。你只能在窗中看到k個數字。每次滑動窗向右移動乙個位置。以下為示例:

窗的位置

最小值最大值

[1  3  -1] -3  5  3  6  7 -13

1 [3  -1  -3] 5  3  6  7 -3

31  3 [-1  -3  5] 3  6  7 -3

51  3  -1 [-3  5  3] 6  7 -3

51  3  -1  -3 [5  3  6] 7 3

61  3  -1  -3  5 [3  6  7] 3

7陣列為[1 3 -1 -35 3 6 7],k為3。

輸入 輸入由兩行組成。第一行包含兩個整數n和k,它們分別是陣列和滑動視窗的長度。第二行有n個整數。輸出

輸出中有兩行。第一行從左到右給出窗中每個位置的最小值,第二行給出最大值。

輸入樣例

8 31 3 -1 -3 5 3 6 7

輸出樣例

-1 -3 -3 -3 3 3

3 3 5 5 6 7

將窗放上去,然後找到這最開始的

k個數的最大值,然後窗最後移乙個單元,繼續找到

k個數中的最大值。這是每個人都會的最直觀的暴力求解法。然而看看n的資料規模,你的心情一定是這樣的

那麼怎麼辦呢?

我們可以引入單調佇列思想。單調,顧名思義,就是數學必修一那個:)。顯然,單調區間內的最值一定在最左或最右。用這個思路來解決這道題,可以避免很多不必要的重複判斷,儲存上次的結果。此演算法的複雜度和空間都遠遠優於暴力求解。

單調佇列的定義如下:

1、維護區間的最值。 2

、去除冗雜狀態

如上題,區間中的兩個元素

a[i],a[j]。

(假設現在再求最大值)

若j>i

且a[j]>=a[i]

,a[j]

比a[i]

還大而且還在後面(目前

a[j]

留在佇列肯定比

a[i]

有用,因為你是往後推,

核心思想!)

3、維護佇列的單調性,最大值是單調遞減序列,最小值反之。 4

、最優選擇在隊首。

用單調佇列解決的程式如下:

#includeusing namespace std;

struct node

v[1010000]; //x表示值,y表示位置 可以理解為下標

int a[1010000],n,m,mx[1010000],mn[1010000];

void getmin()

for(i=m;i<=n;i++)//滑視窗,摩擦摩擦(i為窗內的第乙個數)

{while(head<=tail && v[tail].x>=a[i]) tail--;//刪除不滿足單調性的點

v[++tail].x=a[i],v[tail].y=i;

while(v[head].y

乙個蒟蒻未切的題o o

jzoj 3104.noip2012提高組 疫情控制 就是個二分 貪心,碼量有點長 碼農題 jzoj 3053.noip2012模擬10.25 旅行 我的程式有乙個很大的bug 已改 jzoj 4754.gdoi2017模擬9.4 矩陣 dp題 已切 jzoj 4752.gdoi2017模擬9.4 ...

乙個蒟蒻的hibernate框架安裝

提取碼 x4xv 順便紀念一下pandownload 差不多就是這麼個路徑吧 hibernate release 5.4.14.final.zip hibernate release 5.4.14.final lib required 將他們copy到你web目錄下的web inf lib下面即可。...

從一道題談C 容器內元素的型別約束

c primer 第四版中文267頁,9.1.2 不久前我複習的時候還標記了一下,沒想到理解得還不深刻啊。今天演算法群有提問 這個程式看起來很蛋疼啊,x,y還搞成const.好吧,姑且不說這個了,說一下程式的問題。這個程式直接編譯的話,會有錯誤 但是加了個賦值函式,裡面是空的,就通過編譯了 poin...