POJ 2559 Largest Rectangle in a Histogram ——————单调栈

àì夳堔傛蜴生んèń 2021-11-05 06:38 286阅读 0赞

POJ 2559 Largest Rectangle in a Histogram

现在有 n n n 个宽度为 1 1 1 ,高度分别为 h 1 , h 2 , . . . , h n h_1,h_2,…,h_n h1,h2,…,hn的长方形从左到右组成的柱状图。问里面包含的长方形的最大面积是多少?

下图对应的样例
7
2 1 4 5 1 3 3
结果是 8 ,图中阴影部分
在这里插入图片描述


用单调栈来维护以 h i h_i hi为高度的矩阵块的左端点 L i L_i Li和右端点 R i R_i Ri;

对于一个单调递增栈来说,它具有向前延伸的性质。
当要加入的元素之前有 n n n个栈元素出栈,那么说明这 n n n个出栈元素都会大于或者等于要入栈的元素。
此时,我们需要维护入栈元素可以向前延伸多少个元素(相当于记录它的前面有多少个元素比它大),
而每个栈顶元素都要向出栈了的元素延伸,因为出栈了的元素一定是比它大的元素。
就在 O ( n ) O(n) O(n)的时间复杂度内解决了上述问题…

我们正向维护单调递增栈的话,可以求得 L i L_i Li
我们逆向维护单调递增栈的话,可以求得 R i R_i Ri

最后求一下 h i ∗ ( R i − L i ) h_i*(R_i-L_i) hi∗(Ri−Li) 的最大值就行了

  1. /*--------- Hongjie ----------*/
  2. /**
  3. *        ┏┓   ┏┓+ +
  4. *       ┏┛┻━━━┛┻┓ + +
  5. *       ┃       ┃
  6. *       ┃   ━   ┃ ++ + + +
  7. *       ████━████ ┃+
  8. *       ┃       ┃ +
  9. *       ┃   ┻   ┃
  10. *       ┃       ┃ + +
  11. *       ┗━┓   ┏━┛
  12. *         ┃   ┃
  13. *         ┃   ┃ + + + +
  14. *         ┃   ┃    Code is far away from bug with the animal protecting
  15. *         ┃   ┃ +     神兽保佑,代码无bug
  16. *         ┃   ┃
  17. *         ┃   ┃  +
  18. *         ┃    ┗━━━┓ + +
  19. *         ┃        ┣┓
  20. *         ┃        ┏┛
  21. *         ┗┓┓┏━┳┓┏┛ + + + +
  22. *          ┃┫┫ ┃┫┫
  23. *          ┗┻┛ ┗┻┛+ + + +
  24. */
  25. // #include<bits/stdc++.h>
  26. #include<map>
  27. #include<set>
  28. #include<queue>
  29. #include<stack>
  30. #include<deque>
  31. #include<cmath>
  32. #include<cstdio>
  33. #include<bitset>
  34. #include<string>
  35. #include<vector>
  36. #include<cstring>
  37. #include<iostream>
  38. #include<algorithm>
  39. using namespace std;
  40. typedef long long ll;
  41. typedef pair<int ,int> P;
  42. const int INF = 0x3f3f3f3f;
  43. const int MAXN = 1e5+7;
  44. int n;
  45. int h[MAXN],L[MAXN],R[MAXN];
  46. int st[MAXN];
  47. int main(){
  48. // freopen("../in.txt","r",stdin);
  49. // freopen("../out.txt","w",stdout);
  50. ios::sync_with_stdio(0);
  51. cin.tie(0);
  52. while(cin>>n&&n) {
  53. for(int i=0;i<n;++i)
  54. cin>>h[i];
  55. stack<int> s;
  56. for(int i=0;i<n;++i) {
  57. while(!s.empty() && h[s.top()]>=h[i])
  58. s.pop();
  59. L[i] = (int)s.size() == 0 ? 0 : s.top() + 1;
  60. s.push(i);
  61. }
  62. while(!s.empty())
  63. s.pop();
  64. for(int i=n-1;i>=0;--i){
  65. while(!s.empty() && h[s.top()]>=h[i])
  66. s.pop();
  67. R[i] = (int)s.size() == 0 ? n : s.top();
  68. s.push(i);
  69. }
  70. ll ans = 0;
  71. for(int i=0;i<n;++i)
  72. ans = max(ans, (ll)h[i]*(R[i] - L[i]));
  73. cout<<ans<<endl;
  74. }
  75. return 0;
  76. }

发表评论

表情:
评论列表 (有 0 条评论,286人围观)

还没有评论,来说两句吧...

相关阅读