D - Bad Hair Day POJ - 3250 -單調棧-第一彈
阿新 • • 發佈:2018-12-01
-
單調棧是什麼:
- 單調棧就是一個單調遞增/遞減的棧,每個元素僅入棧一次,例如維護一個遞增的單調棧的話,若入棧元素小於棧頂元素就要將棧中小於入棧元素的元素全部pop出去,再push這個元素,這樣就在O(n)的複雜度內維護了一個單調棧
-
單調棧能做什麼
- 1.最基礎的應用就是給定一組數,針對每個數,尋找它和它右邊第一個比它大的數之間有多少個數。
- 2.給定一序列,尋找某一子序列,使得子序列中的最小值乘以子序列的長度最大。
- 3.給定一序列,尋找某一子序列,使得子序列中的最小值乘以子序列所有元素和最大。
- 應用1對應題目:
-
D - Bad Hair Day
- POJ - 3250
- 題意:cow 可以看見右邊strictly shorter嚴格比他矮的cow 求一下所有cow 能看見的總數
- 思路:維護一個單調遞減的棧,入棧元素為結構體(需要儲存其高度與位置),遇到當前元素
- 大於等於棧內元素時,棧頂元素開始出棧,出棧是累計結果,因為直到此處是棧內元素所能看見的cow的數量。
- 最後再依次處理一下棧內剩下的元素。它們所能看到的就是一直到結尾了 ,
-
#include<stdio.h> #include<stack> using namespace std; #define ll long long struct node { int id,h; } a; stack<node>stk; ll n,ans; int main() { scanf("%lld",&n); for(int i=1; i<=n; i++) { scanf("%d",&a.h); a.id=i; if(stk.empty()) stk.push(a); else { while(!stk.empty()&&stk.top().h<=a.h) { ans+=i-stk.top().id-1; stk.pop(); } stk.push(a); } } while(!stk.empty()) { ans+=n-stk.top().id; stk.pop(); } printf("%lld\n",ans); return 0; }