限制大小的关键在于某一个矩形向左可以到什么地方,向右可以到什么地方。
如果可以得知这个长度,再乘以该矩形的高度就是我们所需要的该矩形的最大面积。
如果可以得知这个长度,再乘以该矩形的高度就是我们所需要的该矩形的最大面积。
然后枚举求出所有矩形的最大面积,求最大的那一个就可以了。
那么如何去向左和向右寻找最远的地方呢?我们可以将问题转换成找最近的阻挡点,那么就可以使用一个单调栈来维护这个最近的阻挡点。如果当前是最小的那一个,那么就不存在什么阻挡点所以直接将他的下标填到极限的地方,否则就去栈里面不断将大于等于该矩形高度的不断出栈,最后剩下的就是最近的阻挡点。右边的过程同样如此。
//限制大小的关键在于某一个矩形向左可以到什么地方,向右可以到什么地方。 //如果可以得知这个长度,再乘以该矩形的高度就是我们所需要的该矩形的最大面积。 //然后枚举求出所有矩形的最大面积,求最大的那一个就可以了。 #include <bits/stdc++.h> typedef long long ll; using namespace std; const int maxn = 100000+10; ll a[maxn]; ll zuo[maxn]; ll you[maxn]; void find_zuo(int n) { stack<ll> st; for (int i=1;i<=n;i++) { while (!st.empty()&&a[st.top()]>=a[i]) { st.pop(); } if (st.empty()) zuo[i] = 0; else zuo[i] = st.top(); st.push(i); } } void find_you(int n) { stack<ll> st; for (int i=n;i>=1;i--) { while (!st.empty()&&a[st.top()]>=a[i]) { st.pop(); } if (st.empty()) you[i] = n+1; else you[i] = st.top(); st.push(i); } } void Merge(int n) { for (int i=1;i<=n;i++) { zuo[i] = you[i] - zuo[i] - 1; } } int main() { int n; cin>>n; while (n) { for (int i=1;i<=n;i++) { cin>>a[i]; } find_zuo(n); find_you(n); Merge(n); //求得结果 ll ans = 0; for (int i=1;i<=n;i++) { ans = max(ans, a[i]*zuo[i]); } cout<<ans<<endl; cin>>n; } return 0; }