Week5 作业 A

题目描述:

给一个直方图,求直方图中的最大矩形的面积。例如,下面这个图片中直方图的高度从左到右分别是2, 1, 4, 5, 1, 3, 3, 他们的宽都是1,其中最大的矩形是阴影部分

 思路:

对于第i个矩形,以其高度h[i]能组成的最大矩形是通过如下方式求的:找出i左边第一个高度小于h[i]的,和i右边第一个高度大于h[i]的,用长度乘以h[i]就是了。对于每一个矩形进行这样的操作,找出其中的最大值就行了。

找的过程可以用单调栈来解决,这里以找右边界R[i]为例:从1到n进行遍历,维护一个单调栈(从栈底到栈顶递增),当进入的元素a[i]大于等于栈顶元素时,进栈,否则弹出栈顶元素x,同时说明x的最右边界就是i-1,然后继续判断栈顶元素,直到栈顶元素小于等于a[i],然后把i进栈,继续向后搜索;

所有元素都搜索完毕后,可能有一部分的R[i]==0,说明这些元素的右边界没确定,也就是说,从i到n一直在递增;这些元素一定都还在栈中,处理一下即可。

找出每个i的左右边界之后,取 h[i]*(R[i]-L[i]) 的最大值即可。

代码:

 1 #include <cstdio>
 2 #include <iostream>
 3 #include <stack>
 4 #include <cstring>
 5 using namespace std;
 6 const int MAXN=1e5+5;
 7 typedef long long ll;
 8 stack<int> S;
 9 ll a[MAXN],ans;
10 int R[MAXN],L[MAXN];  //R[i]=k表示a[i]右边的边界是k,其元素是a[k] 
11 int main()
12 {
13     int n;
14     while( scanf("%d",&n) && n!=0 )
15     {
16         memset( a,0,sizeof(a) );
17         memset( R,0,sizeof(R) );
18         memset( L,0,sizeof(L) );
19         ans=0;
20         for(int i=1;i<=n;i++)
21         {
22             scanf("%d",a+i);
23             while( !S.empty() && a[ S.top() ]>a[i] )
24             {
25                 R[ S.top() ] =i-1;             //如果遇到连续递增的,则其R[i]=0;否则一定R[i]!=0; 
26                 S.pop();
27             }
28             S.push(i);
29         }
30         while( !S.empty() )    //如果栈中还有元素则说明其R[i]=0;
31         {
32             R[ S.top() ]=n;
33             S.pop();
34         } 
35         for(int i=n;i>=1;i--)
36         {
37             while( !S.empty() && a[ S.top() ]>a[i] )
38             {
39                 L[ S.top() ] =i+1;             //如果遇到连续递增的,则其L[i]=0;否则一定L[i]!=0; 
40                 S.pop();
41             }
42             S.push( i );     
43         }
44         while( !S.empty() )    //如果栈中还有元素则说明其L[i]=0;
45         {
46             L[ S.top() ]=1;
47             S.pop();
48         } 
49         for(int i=1;i<=n;i++)
50         {
51             ll tmp=a[i]*(R[i]-L[i]+1);
52             ans=max( ans,tmp );
53         }
54         cout<<ans<<endl;
55     }
56     return 0;
57 }
原文地址:https://www.cnblogs.com/qingoba/p/12548921.html