cdoj 2015数据结构专题:G - 秋实大哥去打工

来源:互联网 发布:淘宝网羊绒毛衣 编辑:程序博客网 时间:2024/05/02 04:37

天行健,君子以自强不息。地势坤,君子以厚德载物。

天天过节的秋实大哥又要过节了,于是他要给心爱的妹子买礼物。但由于最近秋实大哥手头拮据,身为一个男人,他决定去打工!

秋实大哥来到一家广告公司。现在有n块矩形墙从左至右紧密排列,每一块高为Hi,宽为Wi

公司要求秋实大哥找出一块最大的连续矩形区域,使得公司可以在上面贴出最大的海报。

Input

第一行包含一个整数n,表示矩形墙的个数。

接下来n行,每行有两个整数WiHi,表示第i块墙的宽度和高度。

1n200000,保证WiHi以及最后的答案<231

Output

最大的连续矩形的面积。

Sample input and output

Sample InputSample Output
33 41 23 4
14

最后所得面积的矩形的高一定是给定的某一个已有矩形的高,所以问题简化为求出以各个矩形的高为条件,能达到的最大的宽。求出后遍历一次就能找到最大的面积。

求最大宽分为两部分,向左最大宽和向右最大宽。某个矩形的最大宽即左右最大宽之和减去其本身的宽度,因为其本身宽度在计算左右宽时都加上了,计算了两次。

以求右最大宽为例,维护两个栈,一个记录矩形的编号,一个记录放入矩形的宽度。使得栈顶矩形到栈底矩形高度依次递减。向栈内依次放入矩形,当放入的矩形的高度比栈内矩形的高度低时,栈内矩形能达到的右最大宽及可通过出栈等操作获得,一直到栈内矩形的高度比放入矩形的高度低。如果此时栈内还有矩形,新加入矩形的宽度要加上出栈所有矩形的宽度,相当于记录了对于未出栈的矩形能向右延展的宽度,否则,直接入栈。最后放入完了之后要逐个出栈求出对应的右最大宽直到栈空。

#include <iostream>#include <cstdio>#include <stack>using namespace std;long long w[200005],h[200005];int n;long long rwid[200005],lwid[200005];void run_r(){    stack <int> loc;    stack <long long> wid;    loc.push(0);    wid.push(w[0]);    for(int i = 1; i < n; i++)    {        while(!wid.empty() && h[i] < h[loc.top()])        {            int tem;            rwid[loc.top()] = wid.top();            tem = wid.top();            wid.pop();            loc.pop();            if(!wid.empty())                wid.top() += tem;        }        wid.push(w[i]);        loc.push(i);    }    while(!loc.empty())    {        int tem;        rwid[loc.top()] = wid.top();        tem = wid.top();        wid.pop();        loc.pop();        if(!wid.empty())            wid.top() += tem;    }}void run_l(){    stack <int> loc;    stack <long long> wid;    loc.push(n - 1);    wid.push(w[n - 1]);    for(int i = n - 2; i >= 0; i--)    {        while(!wid.empty() && h[i] < h[loc.top()])        {            int tem;            lwid[loc.top()] = wid.top();            tem = wid.top();            wid.pop();            loc.pop();            if(!wid.empty())                wid.top() += tem;        }        wid.push(w[i]);        loc.push(i);    }    while(!loc.empty())    {        int tem;        lwid[loc.top()] = wid.top();        tem = wid.top();        wid.pop();        loc.pop();        if(!wid.empty())            wid.top() += tem;    }}int main(){    scanf("%d", &n);    long long suf,tem;    for(int i = 0; i < n; i++)        scanf("%lld%lld",&w[i], &h[i]);    suf = 0;    run_r();    run_l();    for(int i = 0; i < n; i++)    {        long long wid;        wid = rwid[i] + lwid[i] - w[i];        tem = wid * h[i];        if(tem > suf)            suf = tem;    }    printf("%lld",suf);    return 0;}



0 0
原创粉丝点击