Let N be the set of all natural numbers {0 , 1 , 2 , . . . }, and R be the set of all real numbers. wi, hi for i = 1 . . . n are some elements in N, and w0 = 0.
Define set B = {< x, y > | x, y ∈ R and there exists an index i > 0 such that 0 <= y <= hi ,∑ 0<=j<=i-1wj <= x <= ∑ 0<=j<=iwj}
Again, define set S = {A| A = WH for some W , H ∈ R + and there exists x0, y0 in N such that the set T = { < x , y > | x, y ∈ R and x0 <= x <= x0 +W and y0 <= y <= y0 + H} is contained in set B}.
Your mission now. What is Max(S)?
Wow, it looks like a terrible problem. Problems that appear to be terrible are sometimes actually easy.
But for this one, believe me, it's difficult.
Define set B = {< x, y > | x, y ∈ R and there exists an index i > 0 such that 0 <= y <= hi ,∑ 0<=j<=i-1wj <= x <= ∑ 0<=j<=iwj}
Again, define set S = {A| A = WH for some W , H ∈ R + and there exists x0, y0 in N such that the set T = { < x , y > | x, y ∈ R and x0 <= x <= x0 +W and y0 <= y <= y0 + H} is contained in set B}.
Your mission now. What is Max(S)?
Wow, it looks like a terrible problem. Problems that appear to be terrible are sometimes actually easy.
But for this one, believe me, it's difficult.
The input consists of several test cases. For each case, n is given in a single line, and then followed by n lines, each containing wi and hi separated by a single space. The last line of the input is an single integer -1, indicating the end of input. You may assume that 1 <= n <= 50000 and w
1h
1+w
2h
2+...+w
nh
n < 10
9.
Simply output Max(S) in a single line for each case.
3 1 2 3 4 1 2 3 3 4 1 2 3 4 -1
12 14【题意】有N个连续的矩形,它们的底边沿着Z轴,宽度为Wi,高为Hi,现在要求这些矩形所能组成的面积最大的连续矩形面积是多少。
【分析】这道题原本正常做法也可以做,但是现在数据量很大,正常做法加优化也要O(n2),所以就要用数据结构的只是了,正好单调栈的操作原理与这个很像,所以就可以用单调栈来做,首先用栈保存矩形,如果高度递增则不断入栈,如果遇到当前输入的比栈顶高度小,则从栈顶开始不断出栈并且计算最大面积,直到栈顶高度小于当前输入高度则停止出栈,并把开始出栈矩形的宽度累加得到totalw,把totalw和当前输入的矩形宽度相加得到当前输入矩形的宽度,并入栈,这样栈中保存的永远都是高度递增的矩形,最后输入完了之后如果栈不为空,则依次出栈并计算最大面积。
用时125ms;
【代码】
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<stack>
using namespace std;
const int N=5e4+5;
typedef long long ll;
int totalw;
struct no
{
int w;
int h;
}node,ss;
stack<no> s;
int max(int x,int y)
{
return x>y?x:y;
}
int main()
{
int t;
while(~scanf("%d",&t)&&t!=-1)
{
int w,h;
int ans=0;
while(t--)
{
scanf("%d %d",&w,&h);
if(s.empty()){//栈空则直接加入
node.w=w;
node.h=h;
s.push(node);
}
else
{
totalw=0;
if(h>s.top().h)//高度保持递增,则直接加入栈顶
{
ss.w=w;
ss.h=h;
s.push(ss);
}
else
{
while(!s.empty()&&s.top().h>h)//栈非空且输入高度小于栈顶高度,出栈,totalw记录出栈矩形宽度和
{
totalw+=s.top().w;
ans=max(ans,totalw*s.top().h);//求矩形面积最大值
s.pop();
}
//现在栈顶矩形高度一定是小于等于输入矩形高度的
//要使栈依然保持递增状态
node.w = w + totalw ;
node.h= h;
s.push(node);
}
}
}
totalw = 0;
while(!s.empty())//栈非空,则再次计算最大面积
{
totalw += s.top().w;
ans = max (ans,totalw*s.top().h);
s.pop();
}
printf("%d\n",ans);
}
return 0;
}