BITOJ 木板墙问题(单调栈)

来源:互联网 发布:java 构架师 编辑:程序博客网 时间:2024/03/29 06:10


木板墙

考古学家在人迹罕至的一块平地上发现了由一堆木板拼成的墙。令人惊奇的是这些木板的宽度都相同!地下的部分都已腐烂,而地上的部分也有高有低,甚至有的地方根本没有木板,所以考古学家决定带走木板覆盖的面积最大的长方形回去研究。 输入: 首先是整数n(1<=n<=100000),表示木板的块数。接下来是n个整数h1,...,hn, 其中0<=hi<=1000000000,它们按照从左到右的顺序表示木板的高度。每块木板的宽度都是1。

最后一个0表示程序的结束。 输出: 其中最大长方形的面积。    木板墙

 测试输入关于“测试输入”的帮助期待的输出关于“期待的输出”的帮助时间限制关于“时间限制”的帮助内存限制关于“内存限制”的帮助额外进程关于“{$a} 个额外进程”的帮助测试用例 1以文本方式显示

  1. 3 2000 2000 2000↵
  2. 7 1 2 5 6 1 3 3↵
  3. 0↵
以文本方式显示
  1. 6000↵
  2. 10↵
1秒64M0

</pre><pre name="code" class="cpp"><pre name="code" class="cpp">/*    方法一:        暴力枚举每个最短板,计算长方形最大面积        时间复杂度=O(n^2)    方法二:        单调栈        枚举每个长方形终点版,起点则通过栈顶元素弹出个数来计算        (为什么不枚举起点,而是枚举终点?            答:从左到右扫描,则计算起点更容易借助之前的信息)        时间复杂度=O(n)        注释用词说明:            木板的起点:包含该木板的长方形的起点木板,                长方形高度为该木板的高度(即该木板在组成长方形的木板中高度最低)    注意精度问题:int先向longlong进行转换,再进行乘法运算*/#include <cstdio>#include <stack>#include <algorithm>#include <cstring>using namespace std;const int maxn=100100;struct BOARD{    int id; //木板编号    int height; //木板高度    int preHigherNum; //该木板之前有多少个连续的比该木板高的木板} board[maxn];int n;stack<BOARD>stac;int main(){    long long ans;    while(!stac.empty()) //清空栈        stac.pop();    while(~scanf("%d",&n) && n)    {        ans=-1;        for(int i=0; i<n; i++)        {            board[i].id=i;            board[i].preHigherNum=0;            scanf("%d",&board[i].height); //生成第i块木板            //若为木板0或木板i不高于栈顶木板,则直接推入栈            //否则,有木板i高于栈顶木板            while(!stac.empty() && board[i].height<stac.top().height)            {                //弹出栈顶木板                BOARD tmp=stac.top();                stac.pop();                //栈顶木板比木板i高,可用来组成长方形,                board[i].preHigherNum+=tmp.preHigherNum+1;                //栈顶木板的终点已确定,                //可以计算以其作为最低板的长方形面积,并与当前结果比较                //先强制转换,再相乘,否则发生溢出错误                ans=max(ans,(long long)                        tmp.height*(long long)(i-tmp.id+tmp.preHigherNum));            }            stac.push(board[i]);//推入木板i        }        while(!stac.empty()) //若栈中有剩余元素        {            //计算以其作为最低板的长方形面积,并与当前结果比较            BOARD tmp=stac.top();            stac.pop();            //先强制转换,再相乘,否则发生溢出错误            ans=max(ans,(long long)(tmp.height)*(long long)(n-tmp.id+tmp.preHigherNum));        }        printf("%lld\n",ans);    }    return 0;}
</pre><p></p><p></p><p>参考资料:http://blog.csdn.net/cxy450019566/article/details/45245645</p><pre>







1 0