单调栈
附大佬博客: https://www.jianshu.com/p/882291e56f12
例题1: hdu1506
A histogram is a polygon composed of a sequence of rectangles aligned at a common base line. The rectangles have equal widths but may have different heights. For example, the figure on the left shows the histogram that consists of rectangles with the heights 2, 1, 4, 5, 1, 3, 3, measured in units where 1 is the width of the rectangles:
Usually, histograms are used to represent discrete distributions, e.g., the frequencies of characters in texts. Note that the order of the rectangles, i.e., their heights, is important. Calculate the area of the largest rectangle in a histogram that is aligned at the common base line, too. The figure on the right shows the largest aligned rectangle for the depicted histogram.
用两个数组l,r记录i可以向两边扩展的下标
附代码:
时间 124ms 空间 3188k
1 #include <iostream>
2 #include <algorithm>
3 #include <stack>
4 #include <cstdio>
5 #include <cstring>
6 using namespace std;
7 #define ll long long
8 const int maxn = 100100;
9 ll a[maxn];
10 int l[maxn],r[maxn];
11 stack <int> s;
12
13 int main()
14 {
15 int n;
16 while(cin>>n && n)
17 {
18 for(int i = 1; i <= n; i++)
19 {
20 scanf("%lld",&a[i]);
21 }
22 while(!s.empty())
23 s.pop();
24 for(int i = 1; i <= n; i++)
25 {
26 while(!s.empty() && a[s.top()] >= a[i])
27 s.pop();
28 if(s.empty())
29 l[i] = 1;
30 else
31 l[i] = s.top()+1;
32 s.push(i);
33 }
34 while(!s.empty())
35 s.pop();
36 for(int i = n; i >= 1; i--)
37 {
38 while(!s.empty() && a[i] <= a[s.top()])
39 s.pop();
40 if(s.empty())
41 r[i] = n+1;
42 else
43 r[i] = s.top();
44 s.push(i);
45 }
46 ll ans = 0;
47 for(int i = 1; i <= n; i++)
48 {
49 ans = max(ans,a[i]*(r[i]-l[i]));
50 }
51 printf("%lld\n",ans);
52 }
53 return 0;
54 }
例题2: poj2796
类似于上面这题,不过有一些坑点,这题来了3次,每一次都忘了补题,然后每一次都没做出来,wa....
时间 844ms 空间 3008k
1 #include <iostream> 2 #include <cstdio> 3 #include <stack> 4 #include <cstring> 5 #include <algorithm> 6 using namespace std; 7 8 #define mem(a) memset(a,0,sizeof(a)) 9 #define ll long long 10 const int maxn = 100100; 11 int a[maxn]; 12 int l[maxn],r[maxn]; 13 ll sum[maxn]; 14 stack <int> s; 15 int main() 16 { 17 int n; 18 while(~scanf("%d",&n)&&n) 19 { 20 for(int i = 1; i <= n; i++) 21 { 22 scanf("%d",a+i); 23 sum[i] = sum[i-1]+a[i]; 24 } 25 while(!s.empty()) 26 s.pop(); 27 for(int i = 1; i <=n; i++)//令a[i]就是某区间最小数 28 { 29 while(!s.empty() && a[i] <= a[s.top()]) 30 { 31 s.pop(); 32 } 33 if(s.empty()) 34 l[i] = 1; 35 else 36 l[i] = s.top()+1; 37 s.push(i); 38 } 39 // for(int i = 1; i <= n; i++) 40 // cout<<l[i]<<' '; 41 // cout<<endl; 42 while(!s.empty()) 43 s.pop(); 44 for(int i = n; i >= 1; i--) 45 { 46 while(!s.empty() && a[i] <= a[s.top()]) 47 { 48 s.pop(); 49 } 50 if(s.empty()) 51 r[i] = n; 52 else 53 r[i] = s.top()-1; 54 s.push(i); 55 } 56 // for(int i = 1; i <= n; i++) 57 // cout<<r[i]<<' '; 58 // cout<<endl; 59 ll ans = -1; 60 int ansl = 0,ansr = 0; 61 for(int i = 1; i <= n; i++) 62 { 63 ll tmp = sum[r[i]]-sum[l[i]-1]; 64 tmp *= a[i]; 65 //cout<<tmp<<endl; 66 if(tmp > ans) 67 { 68 ans = tmp; 69 ansl = l[i]; 70 ansr = r[i]; 71 } 72 } 73 printf("%lld\n",ans); 74 printf("%d %d\n",ansl,ansr); 75 } 76 return 0; 77 }