POJ_2082_Terrible Sets

来源:互联网 发布:db2 设置数据库编码 编辑:程序博客网 时间:2024/06/05 16:25
Terrible Sets
Time Limit: 1000MS Memory Limit: 30000KTotal 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 w1h1+w2h2+...+wnhn < 109.

Output

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

Sample Input

31 23 41 233 41 23 4-1

Sample Output

1214

题目大意:输入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;}