POJ_2082_Terrible Sets

Terrible Sets
Time Limit: 1000MS Memory Limit: 30000K
Total Submissions: 4374 Accepted: 2269

Description

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.

Input

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.

Output

Simply output Max(S) in a single line for each case.

Sample Input

3
1 2
3 4
1 2
3
3 4
1 2
3 4
-1

Sample Output

12
14

题目大意:输入n,表示有n个矩形,接下来有n行,每行输入矩形的长和宽,求这n个连续的矩形能够组成的最大面积。例如样例2,这三个矩形组成长为7,宽为2的矩形时,面积最大,此时面积最大。这样说可能有点模棱两可,具体可以看一下这一份题解的图示:点击打开链接

分析:这是接触的第一道单调栈的题目,用栈来处理的话,感觉特别简单。在这里,我们维护栈里面矩形的高都是非递减的,当遇到一个高比栈顶矩形的高小的矩形的时候,我们就开始处理当前栈所存取的矩形了。这里需要理解的是,由于栈里面的矩形的高都是非递减的,因此当前处理的矩形的最大面积就是(当前矩形的长+前k个矩形的长)*当前的高,这样不断的处理,比较,直到遇到高比现在输入的高小,我们就不处理。那么经过这些处理,此时压入栈的矩形已经变了,变成( TOTAL_W+W , H );但是那为什么不是( W, H )呢?这里我们注意一下,上一步,我们处理的是(W,H)这个矩形之前的矩形,也就是说可能存在( TOTAL_W+W , H )的矩形面积最大,这时我们不能忽略,留待下一次来解决,这就是为什么在最后那里,我们还有一个处理栈的操作的原因之一了。讲了这么多,具体看代码吧~

#include<iostream>
#include<cstring>
#include<string>
#include<algorithm>
#include<cmath>
#include<cstdio>
#include<stack>
using namespace std;
struct node
{
    int w,h;
    node(int w,int h):w(w),h(h){}
};
int main()
{
    int n;
    while(~scanf("%d",&n)&&n!=-1)
    {
        int w,h;
        stack<node> s;
        int MAX=0;
        for(int i=1;i<=n;i++)
        {
            scanf("%d%d",&w,&h);
            if(s.empty()==0)
            {
                if(h>=s.top().h)
                {
                    s.push(node(w,h));
                }
                else
                {
                    int total_w=0,total_h=0;
                    while(s.empty()==0)
                    {
                        if(h>s.top().h)
                            break;
                        total_w+=s.top().w;
                        int area=total_w*s.top().h;
                        if(area>MAX)
                            MAX=area;
                        s.pop();
                    }
                    s.push(node(total_w+w,h));
                }
            }
            else
                s.push(node(w,h));
        }
        int total_w=0,total_h=0;
        while(s.empty()==0)
        {
            total_w+=s.top().w;
            int area=total_w*s.top().h;
            if(area>MAX)
                MAX=area;
            s.pop();
        }
        printf("%d\n",MAX);
    }
    return 0;
}
题目链接: http://poj.org/problem?id=2082

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值