标签:sum blog empty ant mes too getch pow vector
InputThe input contains several test cases. Each test case describes a histogram and starts with an integer n, denoting the number of rectangles it is composed of. You may assume that 1 <= n <= 100000. Then follow n integers h1, ..., hn, where 0 <= hi <= 1000000000. These numbers denote the heights of the rectangles of the histogram in left-to-right order. The width of each rectangle is 1. A zero follows the input for the last test case.OutputFor each test case output on a single line the area of the largest rectangle in the specified histogram. Remember that this rectangle must be aligned at the common base line.Sample Input
7 2 1 4 5 1 3 3 4 1000 1000 1000 1000 0
Sample Output
8 4000
首先考虑最大面积的矩形X的左右边界的性质:
设其左边界为L,右边界为R,则其高H = min{h[i] | L <= i <= R}
此时最大面积为 (R - L + 1) * H
若此时左边界的左边那个矩形的高度 h[L-1] >= H
则左边界可以向左拓展,则新的面积为:
(R - (L-1) + 1) * H > 原面积
则与原假设条件冲突
故左边界左边的那个矩形的高度 :h[L-1] < H
同理右边界右边的那个矩形的高度: h[R+1] < H
设H = h[i]
所以左边界L是满足h[j-1] < h[i]的最大的j,即从i点向左遍历的第一个高度比i小的点的右边一个点
而右边界R是满足 h[j+1] < h[i]的最小的j,即从i点向右遍历第一个高度比i小的点的左边一个点
所以我们可以利用单调栈的性质得到每个确定点,即确定高度的最大面积矩形的左右边界,然后枚举取最大即可。
取自原文:https://blog.csdn.net/wubaizhe/article/details/70136174
细节见我的AC代码:
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include <cmath> #include <queue> #include <stack> #include <map> #include <set> #include <vector> #define sz(a) int(a.size()) #define all(a) a.begin(), a.end() #define rep(i,x,n) for(int i=x;i<n;i++) #define repd(i,x,n) for(int i=x;i<=n;i++) #define pii pair<int,int> #define pll pair<long long ,long long> #define gbtb ios::sync_with_stdio(false),cin.tie(0),cout.tie(0) #define MS0(X) memset((X), 0, sizeof((X))) #define MSC0(X) memset((X), ‘\0‘, sizeof((X))) #define pb push_back #define mp make_pair #define fi first #define se second #define eps 1e-6 #define gg(x) getInt(&x) #define db(x) cout<<"== [ "<<x<<" ] =="<<endl; using namespace std; typedef long long ll; ll gcd(ll a,ll b){return b?gcd(b,a%b):a;} ll lcm(ll a,ll b){return a/gcd(a,b)*b;} ll powmod(ll a,ll b,ll MOD){ll ans=1;while(b){if(b%2)ans=ans*a%MOD;a=a*a%MOD;b/=2;}return ans;} inline void getInt(int* p); const int maxn=1000010; const int inf=0x3f3f3f3f; /*** TEMPLATE CODE * * STARTS HERE ***/ int n; ll h[maxn]; int l[maxn]; int r[maxn]; stack<int> s; int main() { while(~scanf("%d",&n)) { if(n==0) { break; } repd(i,1,n) { scanf("%I64d",&h[i]); } // 1 2 5 7 // while(!s.empty()) { s.pop(); } repd(i,1,n) { while(s.size()&&h[s.top()]>=h[i]) { s.pop(); } if(s.empty()) { l[i]=1; }else { l[i]=s.top()+1; } s.push(i); } while(!s.empty()) { s.pop(); } // 1 2 5 7 for(int i=n;i>=1;i--) { while(s.size()&&h[s.top()]>=h[i]) { s.pop(); } if(s.empty()) { r[i]=n+1; }else { r[i]=s.top(); } s.push(i); } ll ans=0ll; repd(i,1,n) { ans=max(ans,1ll*h[i]*(r[i]-l[i])); } printf("%I64d\n",ans ); } return 0; } inline void getInt(int* p) { char ch; do { ch = getchar(); } while (ch == ‘ ‘ || ch == ‘\n‘); if (ch == ‘-‘) { *p = -(getchar() - ‘0‘); while ((ch = getchar()) >= ‘0‘ && ch <= ‘9‘) { *p = *p * 10 - ch + ‘0‘; } } else { *p = ch - ‘0‘; while ((ch = getchar()) >= ‘0‘ && ch <= ‘9‘) { *p = *p * 10 + ch - ‘0‘; } } }
Largest Rectangle in a Histogram HDU - 1506 (单调栈)
标签:sum blog empty ant mes too getch pow vector
原文地址:https://www.cnblogs.com/qieqiemin/p/10329526.html