這幾天在完成寒假作業的時候,了解到了單調棧和單調佇列的使用,以及作用。
單調棧:單調性,強調單調。棧裡的元素符合增或減。概念很簡單。
剛開始接觸單調棧的時候,看別人**模模糊糊,不是很懂。我寫單調棧都是用陣列模擬,定義乙個s[maxn]陣列,s陣列就是用來記錄棧頂座標。
下面我們來看看單調棧的基礎題。
poj 3250
feel goodpoj 2796
poj 2559
hdu 1506
這裡有三個很基礎的題目,適合我們這種剛接觸單調棧的初學者。
下面附上自己的ac**
/* poj 3250 */
#include#include#include#include#include#include#include#include#include#include#include#include#include#includeusing namespace std;
typedef unsigned long long llu;
const int maxn = 80000 + 5;
llu stc[maxn];
int main()
printf("%llu\n",ans);
}
/* poj 2796 */
#include#include#include#include#include#include#include#include#include#include#include#include#include#includeusing namespace std;
#define manx maxn
const int maxn = 100000 + 5;
int l[manx],r[maxn],stc[maxn];
long long a[maxn],sum[manx];
int main()
int top=0;
for(i=1;i<=n+1;i++)//注意n+1 因為下面r[stc[top]]=i-1;
l[i]=stc[top];//確定左區間座標
stc[++top]=i;
}long long temp,ans=-1,ans1=0,ans2=0;
for(i=1;i<=n;i++)
}printf("%lld\n%lld %lld",ans,ans1+1,ans2);
}
/* poj 2559 || hdu 1506 */
#include#include#include#include#include#include#include#include#include#include#include#include#include#includeconst int maxn = 100000 +10;
using namespace std;
int l[maxn],r[maxn],s[maxn];
int main()
top=0;
for(int i=1; i<=n; i++)//確定左座標 就是i點左邊的 低或者等於這個矩形的位置
top=0;
for(int i=n; i>=1; i--)//確定右座標 同上
//for(int i=1;i<=n;i++)
//coutans=temp;
}cout《最後乙個題畫圖輔助理解更好。總之強調乙個單調性,單調棧不同普通列舉 時間得到了優化。當然是用stlstack也是可以的,只是比陣列模擬的速度慢。
過一陣子,熟悉了dp題 在來更新單調佇列優化dp吧,現在看到dp頭就大
單調棧刷題ing
單調棧分為單調遞增棧和單調遞減棧 同理單調遞減棧即棧內元素保持單調遞減的棧 單調遞增棧即棧內元素保持單調遞增的棧 操作規則 下面都以單調遞增棧為例 如果新的元素比棧頂元素大,就入棧 如果新的元素較小,那就一直把棧內元素彈出來,直到棧頂比新元素小 加入這樣乙個規則之後,會有什麼效果 棧內的元素是遞增的...
單調棧 模板 單調棧模板
biu 單調棧主要用於求取左邊第乙個比它大,或者比它小的數。就比如站隊隨便排成一列,可以求到每個人後面第乙個比他高的人。同理可以推廣至右邊,比它矮均可。這就是單調遞增棧 遞減棧,從前至 棧,從後向前入棧的區別了。單調棧比較抽象,非常具有智慧型的想法,可應用的場景相當少,根據幾個經典題目體會它的用法會...
單調佇列 單調棧
參考文章 單調佇列 poj 2823 給定乙個數列,從左至右輸出每個長度為m的數列段內的最小數和最大數。數列長度 n 106 m n n 106,m n n 106 m n 直接暴力求解複雜度在0 mn 可以考慮維護區間最值,單調佇列則是維護區間佇列的強大 單調佇列的定義 單調佇列實現的大致過程 1...