Monotonous stack
Monotone stack is a special stack, so special that elements within a stack remains monotonic, may be monotonically increasing, or may be monotonically decreasing.
nature:
单调栈里的元素具有单调性
元素加入栈前,会在栈顶端把破坏栈单调性的元素都删除
使用单调栈可以找到元素向左遍历第一个比他小的元素,也可以找到元素向左遍历第一个比他大的元素。
单调栈的维护是 O(n) 级的时间复杂度,因为所有元素只会进入栈一次,并且出栈后再也不会进栈了。
Nothing to say, directly on the title
Tip: Click on the title subject filed directly address
Largest Rectangle in a Histogram
Roughly meaning of the questions:
A plurality of rectangular given from left to right, which is known to this width of the rectangle is 1, the length is not exactly equal.
These rectangles are connected in a row, find the largest rectangular area within the range of these rectangles can get included, the output area.
The request may span a plurality of rectangular rectangular, but not beyond the scope of the original rectangle determined.
Algorithm Analysis && do:
With monotony of thought that deal with the problem and remove the option not possible, maintain a high degree of effectiveness and order a set of strategies
For this question, we need to find each rectangle from left to right right can be extended to a maximum continuous width
Expandable conditions: height of the rectangle is greater than a height equal to the current rectangle
Then calculate the area after we take the max you can find complete
Apparently simple algorithm does not work, we need to use monotonous stack
Accurate to say that:
Maintenance monotonous stack height increasing sequence from the start to the current rectangle rectangle
If the current rectangle on top of the stack below the rectangle, we have been the stack pop elements, until it encounters a rectangle below the current point, in order to maintain the incremental stack, obviously at this time can be extended to the furthest point of the current stack position of the element of top-1, that is, we find the current expansion of border points, while the pop-up rectangle and then merge onto the stack.
Establish a monotonic (incremental) stack, all the elements of each into the stack and popped once. Each element of the stack when updating largest rectangle area.
Disposed within the stack as a rectangle tuple (h, w), h represents the height of the rectangle, w represents the width of the rectangle.
How to push and update it?
① If the current element is larger than the top of the stack or the stack is empty, directly push (h, 1);
② If the current element is less than equal to the top element, the stack is rectangular combined until the current element is greater than the top of the stack or the stack is empty, the combined rectangles (h, sum_width) stack.
③ and updates the maximum area in the process of cumulative width of the stack
Then repeating the above operations ① ~ ③, we linear O (n) for each set of data obtained solution
Precautions:
To maintain the two information stacks Monotone, is a height, the width of the other (easy to calculate the area of a rectangle)
At the same time so that H [n + 1] = 0, to ensure that all all popped rectangular (rectangle is not the last remaining in the stack)
. 1 #include <stdio.h> 2 #include < String .h> . 3 #include <algorithm> . 4 #include < String > . 5 #include <Vector> . 6 #include <Map> . 7 the using namespace STD; . 8 typedef Long Long LL ; . 9 const int INF = 0x3f3f3f3f ; 10 int H [ 100010 ]; // define a rectangle (rectangle) height H . 11 int w [ 100010 ]; // define a rectangle (rectangle) width w 12 is int Stack [ 100010 ]; // array monotonic pseudo-rectangular stack height 13 is int Top; 14 int n-; 15 16 void Solve () // monotone stack algorithm . 17 { 18 is Long Long ANS = 0 ; . 19 for ( int I = 0 ; I <n-+ . 1 ; I ++) // . 1. 1 ~ + n-rectangular scanned again 20 is { 21 is IF (H [I]> Stack [Top]) // if the current rectangle stack directly above the top of the stack, the width 1 (height monotonically increasing compliance properties) 22 { 23 Stack [Top ++] = H [I]; 24 W [Top] = . 1 ; 25 } 26 is the else // otherwise combined continuous rectangular pop stack 27 { 28 int widthsum = 0 ; // pop the stack rectangular combined The total width 29 the while (Stack [Top]> H [I]) // not satisfied continues monotonically increasing height pop 30 { 31 is widthsum + = W [Top]; // total width 32 ANS = max (ANS, ( Long Long widthsum) Stack * [Top]); // area taken max 33 is top--; // pop top rectangular stack 34 is } 35 Stack [Top ++] = [I] H; // the merged rectangular stack good new (height H [i],. 1 + width of width) 36 W [Top] = widthsum + . 1 ; 37 [ } 38 is } 39 the printf ( " % LLD \ n- " , ANS); 40 } 41 is 42 is int main () 43 is { 44 is the while (Scanf ( " % D " , & n-) && n-) / / a plurality of sets of data 45 { 46 is Memset (H,0 , the sizeof (H)); // initialize 47 Memset (W, 0 , the sizeof (W)); 48 Memset (Stack, 0 , the sizeof (Stack)); 49 Top = 0 ; 50 for ( int I = 0 ; I <n-; I ++) // read the height of each rectangle 51 is { 52 is Scanf ( " % D " , & H [I]); 53 is } 54 is Solve (); 55 } 56 is return 0; 57 }
The following is the code STL
1 #include<cstdio> 2 #include<stack> 3 #include <iostream> 4 #include <algorithm> 5 #include<cstring> 6 using namespace std; 7 inline long long read(){ 8 long long x=0,f=1;char c=getchar(); 9 while(c<'0'||c>'9'){if(c=='-')f=-1; C = getchar ();} 10 the while (C> = ' 0 ' && C <= ' . 9 ' ) {X = X * 10 + the C- ' 0 ' ; C = getchar ();} . 11 return F * X; 12 } // sad it, the wrong range, did not change the initial type long long, only to find several burst QWQ 13 is struct Node { 14 int H, W; 15 }; // a deposit height, a deposit width. 16 Long Long S [ 100100 ], ANS = 0 ; . 17 int main () { 18 while(1){ 19 int n=read(); 20 if(n==0)return 0; 21 for(int i=1;i<=n;i++){ 22 s[i]=read(); 23 } 24 stack<node>st; 25 s[n+1]=0; 26 for(int i=1;i<=n+1;i++){ 27 long long W=0; 28 while(!st.empty()&&s[i]<st.top().h){//单调栈!单调递增! 29 W=W+st.top().w; 30 ans=max(ans,W*st.top().h); 31 st.pop(); 32 } 33 st.push((node){s[i],W+1}); 34 } 35 cout<<ans<<endl; 36 ans=0; 37 } 38 }