zoukankan      html  css  js  c++  java
  • Largest Rectangle in a Histogram [POJ2559] [单调栈]

    题意
    一个围挡由n个宽度为1的长方形挡板下端对齐后得到,每个长方形挡板的高度为hi。我们把其抽象成一个图形,问这个图形中包含的面积最大的长方形是多大?

    输入
    多行数据,每行第一个为n,后面n个数,代表hi
    以0为结束

    输出
    每行一个数

    样例输入
    7 2 1 4 5 1 3 3
    4 1000 1000 1000 1000
    0
    样例输出
    8
    4000

    分析
    我们定一个中心为i,矩形高度为Hi,设他能在一个区间[l,r]中存在,必满足j∈[l,r]使Hj≥Hi。如果Hl-1≥Hi,显然可以继续向右扩张,那么Hl-1一定小于Hi,所以l-1是[1,i]中最后一个小于Hi的。那我们从左向右扫维护所有比Hi小的标号,形成一个单调递增的栈,栈顶即是他的左边界。同理维护右边界。

    代码

     1 #include<set>
     2 #include<map>
     3 #include<queue>
     4 #include<stack>
     5 #include<cmath>
     6 #include<cstdio>
     7 #include<cstring>
     8 #include<iostream>
     9 #include<algorithm>
    10 #define RG register int
    11 #define rep(i,a,b)    for(RG i=a;i<=b;++i)
    12 #define per(i,a,b)    for(RG i=a;i>=b;--i)
    13 #define ll long long
    14 #define inf (1<<29)
    15 #define maxn 100005
    16 using namespace std;
    17 int n;
    18 ll num[maxn],L[maxn],R[maxn];
    19 struct D{
    20     int h,id;
    21 };
    22 stack<D> stk;
    23 inline int read()
    24 {
    25     int x=0,f=1;char c=getchar();
    26     while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
    27     while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
    28     return x*f;
    29 }
    30 
    31 void work()
    32 {
    33     int id;
    34     while(!stk.empty()) stk.pop();
    35     rep(i,1,n)
    36     {
    37         while(!stk.empty()&&stk.top().h>=num[i])    stk.pop();
    38         if(!stk.empty())    id=stk.top().id;
    39         else                id=0;
    40         L[i]=id+1;
    41         stk.push((D){num[i],i});
    42     }
    43     while(!stk.empty()) stk.pop();
    44     per(i,n,1)
    45     {
    46         while(!stk.empty()&&stk.top().h>=num[i])    stk.pop();
    47         if(!stk.empty())    id=stk.top().id;
    48         else                id=n+1;
    49         R[i]=id-1;
    50         stk.push((D){num[i],i});
    51     }
    52     ll ans=0;
    53     rep(i,1,n)    ans=max(ans,num[i]*(R[i]-L[i]+1));
    54     printf("%lld
    ",ans);
    55 }
    56 
    57 int main()
    58 {
    59     //freopen("a","r",stdin);
    60     while(1)
    61     {
    62         n=read();if(!n)    return 0;
    63         rep(i,1,n) num[i]=read();
    64         work();
    65     }
    66     return 0;
    67 }
    View Code
  • 相关阅读:
    深入研究java.lang.Runtime类
    全国省市级联数据sql语句 mysql版
    Tesseract——OCR图像识别 入门篇
    Linux数组array基础
    Shell编程中Shift的用法
    对于shell脚本参数获取时的一点小技巧
    RPM是RedHat Package Manager(RedHat软件包管理工具)
    shell 练习
    shell学习总结之自定义函数
    C# 获取汉字的拼音首字母和全拼(含源码)
  • 原文地址:https://www.cnblogs.com/ibilllee/p/9343804.html
Copyright © 2011-2022 走看看