普通棧就5個操作
#include0.stack《型別》 名字; 建立
1.名字.push(元素); 壓入棧變為新的棧頂
2.m=名字.top(); 獲取棧頂元素
3.名字.pop() ; 彈出棧頂元素
4.length=名字.size() 獲取棧內元素長度
ps: 對於 順序棧和鏈棧 相對於普通棧來說 效率會相對高一點
(普通棧考慮太多東西從而使效率降低 而對某一專一問題用順序棧 和 鏈棧 就可以解決效率高些嘛… )
然後 三類題目;
1.最基礎的應用就是給定一組數,針對每個數,尋找它和它右邊第乙個比它大的數之間有多少個數。 poj3250
2.給定一串行,尋找某一子串行,使得子串行中的最小值乘以子串行的長度最大。poj2559
3.給定一串行,尋找某一子串行,使得子串行中的最小值乘以子串行所有元素和最大。poj3494
小生不才,百思不得其解…於是偷瞄答案…我去還可以醬紫~;
0.poj3250
仔細看看大神**
個人題解
//為什麼會超過int型……
#include
#include
#include
#include
#define inf 0x3f3f3f3f
using
namespace std;
typedef
long
long ll;
intmain()
else
st.push
(i);
//當所有破壞棧的單調性的元素都出棧後,將當前元素入棧 }}
printf
("%lld\n"
,ans);}
return0;
}
1.poj2559
這個要好好看 ,我是真沒看懂
用紙和筆推演了一遍才看明白
(最好能自己推…看我寫的注意點…容易變傻(我都感覺太細了))
#include
#include
#include
#include
using
namespace std;
typedef
long
long ll;
intmain()
else
st.push
(top)
;//只將可以延伸到的最左端的位置入棧
a[top]
=a[i]
;//並修改該位置的值 }}
printf
("%lld\n"
,ans);}
return0;
}
注意點:
0.我用c++寫的 tle 了幾次 可能要用scanf() 以及printf();
wr a陣列沒有用long long ;然後終於…ac!
1.由於咱們這個 棧是單調遞增的所以後面的元素一定大於前面的;
醬紫就意味著 i到top(這個是棧頂元素也就是a的下標吧)之間的資料的公共部分是a[top];
也就是tmp 是目前的的 公共面積值;
2.更新單調棧內元素 只要把最後乙個大於a[i] 的下標送進去也就是top
然後把 a[top]更新為新的最小的值a[i]至於原因嗎:因為到i為止最大的就是他了…
相當於更新 新的單調遞增棧 ; 其次就是我們要用距離 * 最小值=tmp所以
一定要將i能變成的a的最小的下標加入到單調棧中去嘛~可以當作x-y座標系來看這個題;
2.poj3494
感覺很巧,大神思路很すごい
大神**
感覺還是看我的**吧…自己看思路寫的…你仔細研究過2559應該能看懂吧…大神**有解析
#include
#include
#include
#include
using
namespace std;
intmain()
a[n+1]
=-1;
//設最後元素為最小值,以最後讓棧內元素出棧
for(j=
1;j<=n+
1;j++
)else
st.push
(top)
;//將最後一次出棧的棧頂元素延伸併入棧
a[top]
=a[j]
;//修改其對應的值 }}
}printf
("%d\n"
,ans);}
return0;
}
3.poj2796
…心態也就呢樣了…
個人解析在下面…也就理解理解了…感覺就會說句 なるほど
#include
#include
#include
using
namespace std;
typedef
long
long ll;
intmain()
a[n+1]
=-1;
//將最後乙個設為最小值,以最後讓棧內元素全部出棧
ans=0;
for(i=
1;i<=n+
1;i++
)else
} st.
push
(top)
;//將最後一次出棧的棧頂元素入棧
a[top]
=a[i]
;//將其向左向右延伸並更新對應的值 }}
printf
("%lld\n"
,ans)
;printf
("%d %d\n"
,pos1,pos2-1)
;}return0;
}
現將每乙個的字首和求出
對a陣列單調遞增 …將其下標加入棧中然後遇到小於的棧頂的 就求區間和(sum[i-1]-sum[top-1])*a[top];
彈出棧頂就這個樣子 因為單調遞增 所以如果每次彈出的棧頂一定是區間 內最小的a; 別忘記更新棧
將最後乙個彈出的棧頂入棧 並且將其值更新為新的最小值
入棧原因感覺就像是 劃分了乙個區域(看做乙個點)/斷點(新的起點) 比如1234 1234-1 或者1234 0 12345-1
參考文章
單調佇列和單調棧例題
1 單調佇列 給出乙個長度為n的序列和區間長度k 從左向右對每乙個長度為k的區間詢問最大值和最小值。思路 對於最小值,考慮維護乙個遞增的雙端佇列,每次入隊時將隊尾比當前入隊元素的全部刪除,每次取隊首並且判斷是否在當前區間內即可 author hairu,wu from ahut include in...
單調棧與單調佇列簡單例題
poj3250 題意 有n只奶牛排成一列向右看,每頭奶牛只能看到比自己矮的奶牛,即會被高的奶牛擋住後面,問共有多少只奶牛能被看到 思路 考慮每頭奶牛能被前面牛看到的次數,也就是從他左邊開始單調遞減的序列的長度,用單調棧維護即可 include includeusing namespace std c...
單調棧 模板及相應例題
單調棧可以存一段元素每個之前第乙個比它小的元素的下標,沒有的置為 1。以下是單調遞增棧的模板,即棧中的元素為單調遞增的。在入棧之前記錄當前元素左邊第乙個比他小的元素的下標 for int i 1 i n i 以下是單調遞減棧的模板,即棧中的元素為單調遞減的,若當前元素比棧頂元素大,所以棧頂元素為第乙...