单调栈

 

 

附大佬博客:  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 }
例题1

 

例题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 }
例题2

 

posted on 2019-08-11 16:34  By_布衣  阅读(129)  评论(0编辑  收藏  举报

导航