POJ 2559 Largest Rectangle in a Histogram 单调栈学习

来源:互联网 发布:美国警察知乎 编辑:程序博客网 时间:2024/06/16 05:38

【题意】

            给定从左到右多个矩形,已知这此矩形的宽度都为1,长度不完全相等。这些矩形相连排成一排,求在这些矩形包括的范围内能得到的面积最大的矩形,打印出该面积。所求矩形可以横跨多个矩形,但不能超出原有矩形所确定的范围。

         

【解题方法】

          过程来自BLOG:点击打开链接

          至于单调栈是啥玩意和为啥这里要用单调栈,可以参考下这里:点击打开链接

          建立一个单调递增栈,所有元素各进栈和出栈一次即可。每个元素出栈的时候更新最大的矩形面积。

          设栈内的元素为一个二元组(x, y),x表示矩形的高度,y表示矩形的宽度。

          若原始矩形高度分别为2,1,4,5,1,3,3

          高度为2的元素进栈,当前栈为(2,1)

          高度为1的元素准备进栈,但必须从栈顶开始删除高度大于或等于1的矩形,因为2已经不可能延续到当前矩形。删除(2,1)这个元素之后,更新最大矩形面积为2*1=2,然  后把它的宽度1累加到当前高度为1的准备进栈的矩形,然后进栈,当前栈为(1,2)

高度为4的元素进栈,当前栈为(1,2) (4,1)

高度为5的元素进栈,当前栈为(1,2) (4,1) (5,1)

高度为1的元素准备进栈,删除(5,1)这个元素,更新最大矩形面积为5*1=5,把1累加到下一个元素,得到(4,2),删除(4,2),更新最大矩形面积为4*2=8,把2累加到下一个元素,得到(1,4),1*4=4<8,不必更新,删除(1,4),把4累加到当前准备进栈的元素然后进栈,当前栈为(1,5)

高度为3的元素进栈,当前栈为(1,5) (3,1)

高度为3的元素准备进栈,删除(3,1),不必更新,把1累加到当前准备进栈的元素然后进栈,当前栈为(1,5) (3,2)

把余下的元素逐个出栈,(3,2)出栈,不必更新,把2累加到下一个元素,当前栈为(1,7),(1,7)出栈,不必更新。栈空,结束。

最后的答案就是8。


【AC代码】

////Created by just_sort 2016/1/5//Copyright (c) 2016 just_sort.All Rights Reserved////#include <ext/pb_ds/assoc_container.hpp>//#include <ext/pb_ds/tree_policy.hpp>//#include <ext/pb_ds/hash_policy.hpp>#include <set>#include <map>#include <queue>#include <stack>#include <cmath>#include <cstdio>#include <time.h>#include <cstdlib>#include <cstring>#include <sstream> //isstringstream#include <iostream>#include <algorithm>using namespace std;//using namespace __gnu_pbds;typedef long long LL;typedef pair<int, LL> pp;#define REP1(i, a, b) for(int i = a; i < b; i++)#define REP2(i, a, b) for(int i = a; i <= b; i++)#define REP3(i, a, b) for(int i = a; i >= b; i--)#define CLR(a, b)     memset(a, b, sizeof(a))#define MP(x, y)      make_pair(x,y)const int maxn = 1e6 + 10;const int maxm = 2e5;const int maxs = 10;const int maxp = 1e3 + 10;const int INF  = 1e9;const int UNF  = -1e9;const int mod  = 1e9 + 7;int gcd(int x, int y) {return y == 0 ? x : gcd(y, x % y);}//typedef tree<int,null_type,less<int>,rb_tree_tag,tree_order_statistics_node_update>order_set;//headstruct node{    int height, num;}s[maxn];int top;int main(){    int n;    while(scanf("%d", &n) != EOF)    {        if(n == 0) break;        top = 0;        LL ans = 0, tot , tmp, x;        REP1(i, 0, n){            scanf("%lld", &x);            tmp = 0;            while(top > 0 && s[top - 1].height >= x){                tot = s[top - 1].height * (s[top - 1].num + tmp);                if(tot > ans) ans = tot;                tmp += s[top - 1].num;                --top;            }            s[top].height = x;            s[top].num = tmp + 1;            ++top;        }        tmp = 0;        while(top > 0){            tot = s[top - 1].height * (s[top - 1].num + tmp);            if(tot > ans) ans = tot;            tmp += s[top - 1].num;            --top;        }        printf("%lld\n", ans);    }    return 0;}



0 0
原创粉丝点击