天行健,君子以自强不息。地势坤,君子以厚德载物。
天天过节的秋实大哥又要过节了,于是他要给心爱的妹子买礼物。但由于最近秋实大哥手头拮据,身为一个男人,他决定去打工!
秋实大哥来到一家广告公司。现在有 n 块矩形墙从左至右紧密排列,每一块高为 Hi ,宽为 Wi 。
公司要求秋实大哥找出一块最大的连续矩形区域,使得公司可以在上面贴出最大的海报。
Input
第一行包含一个整数 n ,表示矩形墙的个数。
接下来 n 行,每行有两个整数 Wi , Hi ,表示第 i 块墙的宽度和高度。
1≤n≤200000 ,保证 Wi , Hi 以及最后的答案 <231 。
Output
最大的连续矩形的面积。
Sample input and output
Sample Input | Sample Output |
---|---|
3 3 4 1 2 3 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;
}