佇列與棧(待補訂)

2022-10-08 22:06:27 字數 1288 閱讀 2321

棧的最基本用途可能就是表示式求值了

p1310 [noip2011 普及組] 表示式的值

大概捋一下轉化過程

如果是左括號或乘號,直接入棧

如果是右括號,一直彈棧知道出來左括號

如果是加號,則先彈棧直到沒有乘號

乘號就直接放

單調棧是一種快速求解序列中每個位置左右第乙個大於/小於自己值的位置的演算法,在大部分情況下可以很好地代替笛卡爾樹

具體流程省略

直方圖中最大的矩形

模板題p4147 玉蟾宮

把一維變成二維了而已,預處理每行上方最長連續高度即可,然後再跑最大矩形

這裡再介紹一下懸線法

首先預處理 \(up[i][j]\) 表示向上最大高度,即懸著的「線」

那麼對於每條線只要知道左右最遠能移動到的位置即可

\(l[i][j]\) 和 \(r[i][j]\) 就是這個左右

如果上一行這一列不是障礙,那麼 \(l,r\) 分別取 \(min\),否則意味著開啟一塊新的矩形

單調佇列可以用於優化如下型別的 \(dp\) 轉移:

\[f_i=max_\

\]要求 \(l_ir\) 和 \(r_i\) 單調,且 \(val(i,j)\) 之和 \(i\) 與 \(j\) 中的乙個有關(指沒有乘積項)

下面的例子直接寫出 \(dp\) 方程來進行優化

\[f[i][j]=max_

\]發現 \(val\) 部分只與 \(k\) 有關,而當 \(j\) 變大 \(1\) 的時候,候選 \(k\) 集合也是單調的,那麼用單調佇列維護即可

\[f[i]=min_\) 都放入堆中,動態查詢出乙個最大的轉移

佇列在動態最值中的應用

p2827 [noip2016 提高組] 蚯蚓

以這道題為例

p7078 [csp-s2020] 貪吃蛇

畢竟蛇與蚯蚓是類似的生物,這道題中也用到了類似的思想,詳見這篇部落格

p6033 [noip2004 提高組] 合併果子 加強版

構建哈夫曼樹的時候同樣可以用這種方式代替過慢的堆

b. 第二題

甚至跑最長路都可以用這種技巧優化

總之用到堆並且時間挺卡的題都想想這個吧~

佇列與棧的轉化

棋盤矩乘啥的都先不說了

可以發現維護出的字首積當隊首出隊時貢獻是不能刨去的,因為不滿**換律

那麼維護兩個棧,每次有插入操作直接插在第二個棧後面,有刪除操作,能彈第乙個就彈第乙個,否則把第二個棧中所有元素拿出來放進第乙個,順便處理字首積

這樣很好地做到了矩乘順序的倒序,而每個元素出棧一次,複雜度也得到了保證

棧與佇列 建立棧 佇列

陣列棧 完成stack createstack int maxelements 函式,該函式建立乙個棧,maxelements為與分配的棧空間大小 棧可用空間為array 0,maxelements 1 typedef int elemtype struct stackrecord typedef ...

棧 佇列與優先佇列

123 45 include stack int s 入棧 push 出棧 pop 取棧頂top 123 45 include queue int s 入隊 push 出隊 pop 取隊首元素 front 不刪除 123 4priority queue int pq 入隊 push 出隊 pop 取...

棧 佇列與優先佇列

123 45 include stack int s 入棧 push 出棧 pop 取棧頂top 123 45 include queue int s 入隊 push 出隊 pop 取隊首元素 front 不刪除 123 4priority queue int pq 入隊 push 出隊 pop 取...