【题解】Largest Rectangle in a Histogram [SP1805] [POJ2559]


【题目描述】

传送: \(Largest\) \(Rectangle\) \(in\) \(a\) \(Histogram\) \([SP1805]\) \([POJ2559]\)

同一水平线上有 \(n\) 个矩形,构成了一个柱状多边形,矩形宽度均为 \(1\),高度不同。如图:



你需要在多边形中框选出一个矩形,使其面积最大,如图阴影部分。

【输入】

每组数据包含一个整数 \(n\),以及 \(n\) 个整数 \(hi\) 。

结尾以一个单独的 \(0\) 结尾。

【输出】

对于每组数据,直接输出这个最大面积 。

【样例】

输入:
7 2 1 4 5 1 3 3
4 1000 1000 1000 1000
0 输出:
8
4000

【分析】

有两种解法,递推和单调栈。

【递推】

问题转换:

假定我们选定了某一个矩形的高,那么由这个高所能得到的最大面积,就是从这个矩形的位置出发,看它最多能向左,右两边延伸多远的距离,并且乘以选定的这个高度。

如果我们能预处理出每个点向左右两边能到达的最远距离,那么这个题就 \(so\) \(easy\)。

如何求一个点向左,右延伸所能到达的极限?

对于每一个位置 \(i\),我们先把它与上一个位置 \(i-1\) 的高度作比较,如果 \(h[i] \leqslant h[i-1]\),那么 \(i-1\) 的左极限 \(L[i-1]\) 也可作为 \(i\) 的左极限。而如果 \(h[\) \(L[i-1]-1\) \(]\) \(\leqslant h[i]\),那么 \(L[i]=L[i-1]-1\) 。

右极限求法同上。

【Code】

#include<algorithm>
#include<cstdio>
#define LL long long
using namespace std;
int n,a[100005],l[100005],r[100005];LL s,ans;
int main(){
while(scanf("%d",&n)!=EOF){
if(!n)break;
ans=0;
for(int i=1;i<=n;i++){
scanf("%d",&a[i]);
l[i]=r[i]=i;//左右极限都初始化为它自己
while(l[i]>1&&a[l[i]-1]>=a[i])l[i]=l[l[i]-1];
}
for(int i=n;i;i--)
while(r[i]<n&&a[r[i]+1]>=a[i])r[i]=r[r[i]+1];
for(int i=1;i<=n;i++)//扫描,对每个点进行一次择优
ans=max(ans,(LL)a[i]*(r[i]-l[i]+1));
printf("%lld\n",ans);
}
}

【单调栈】

建立一个栈存储所有矩形的高度和宽度,宽度全部初始化为 \(1\) 。

每当读入一个点 \(i\) 的高度,判断如果它比上一个点 \(i-1\) 低,那么就进行一次假定选择 \(i-1\) 的高度的计算,计算方法就是不停的出栈,并且不断累加弹出的矩形宽度 \(wide\) ,每弹出一个,就用 \(wide\) 乘以这个弹出的矩形的高度,并且与 \(ans\) 进行一次择优。一直弹到当栈顶矩形高小于等于 \(h[i]\) 时,把一个宽度为 \(wide+1\),高度为 \(h[i]\) 的新矩形入栈。

如果它比上一个高,则直接入栈。

为方便处理最后剩余的矩形,\(把 h[n+1]\) 赋值为一个极大值。

正确性?

而实际上刚刚这样的弹栈边计算计算的方法只计算了每个点在局部所能制造出的面积。只计算每个点的局部最优显然不能得到正确答案,但它对全局所能产生影响的,仅有高度小于等于新矩形高度的下面部分,至于上面的,在以后永远也不会再选到,所以弹出后直接留下宽度送给新矩形即可保留它对全局的影响。

【Code】

#include<algorithm>
#include<cstdio>
int i,n,t,wi,a[100005],Q[100005],W[100005];
long long ans;
int main(){
while(scanf("%d",&n)!=EOF){
if(!n)break;
for(i=1;i<=n;i++)scanf("%d",&a[i]);
ans=a[n+1]=t=0;//提前预处理a[n+1];清空栈
for(i=1;i<=n+1;i++)
if(a[i]>Q[t])Q[++t]=a[i],W[t]=1;//如果仍保持单调性,则直接入栈
else{
wi=0;
while(t&&a[i]<=Q[t])ans=std::max(ans,(long long)(wi+=W[t])*Q[t--]);
//每弹出一个就计算一下:如果选定当前这个矩形向左最多能获得多大的面积收益
Q[++t]=a[i],W[t]=wi+1;//合并且入栈
}
printf("%lld\n",ans);
}
}

【题解】Largest Rectangle in a Histogram [SP1805] [POJ2559]的更多相关文章

  1. POJ2559 Largest Rectangle in a Histogram —— 单调栈

    题目链接:http://poj.org/problem?id=2559 Largest Rectangle in a Histogram Time Limit: 1000MS   Memory Lim ...

  2. poj2559 Largest Rectangle in a Histogram(单调栈)

    Description A histogram is a polygon composed of a sequence of rectangles aligned at a common base l ...

  3. [POJ 2559]Largest Rectangle in a Histogram 题解(单调栈)

    [POJ 2559]Largest Rectangle in a Histogram Description A histogram is a polygon composed of a sequen ...

  4. [POJ2559&POJ3494] Largest Rectangle in a Histogram&Largest Submatrix of All 1’s 「单调栈」

    Largest Rectangle in a Histogram http://poj.org/problem?id=2559 题意:给出若干宽度相同的矩形的高度(条形统计图),求最大子矩形面积 解题 ...

  5. POJ2559 Largest Rectangle in a Histogram (单调栈

    Largest Rectangle in a Histogram Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 26012 ...

  6. NYOJ-258/POJ-2559/HDU-1506 Largest Rectangle in a Histogram,最大长方形,dp或者单调队列!

                                         Largest Rectangle in a Histogram 这么经典的题硬是等今天碰到了原题现场懵逼两小时才会去补题.. ...

  7. 题解报告:poj 2559 Largest Rectangle in a Histogram(单调栈)

    Description A histogram is a polygon composed of a sequence of rectangles aligned at a common base l ...

  8. 【题解】hdu1506 Largest Rectangle in a Histogram

    目录 题目 思路 \(Code\) 题目 Largest Rectangle in a Histogram 思路 单调栈. 不知道怎么描述所以用样例讲一下. 7 2 1 4 5 1 3 3 最大矩形的 ...

  9. DP专题训练之HDU 1506 Largest Rectangle in a Histogram

    Description A histogram is a polygon composed of a sequence of rectangles aligned at a common base l ...

随机推荐

  1. uboot向kernel的传参机制——bootm与tags

    http://blog.csdn.net/skyflying2012/article/details/35787971 最近阅读代码学习了uboot boot kernel的过程以及uboot如何传参 ...

  2. wordpress列表页如果文章没有缩略图就显示默认图片

    有时我们在设计wordpress模板时需要考虑是否有特色图,在分类页上如果一些文章有缩略图一些没有那就有点参差不齐不美观,有没办法设置如果没有文章缩略图则自动显示默认图呢?可以的,随ytkah一起来看 ...

  3. meta设置与去除默认样式--移动端开发整理笔记(一)

    视口设置: <meta name="viewport" content="width=device-width,user-scalable=no,initial-s ...

  4. MAC上配置idea环境时排查问题

    现象:没有使用走公司maven仓库的setting.xml文件时,只有公司内部依赖 没有找到在idea的maven配置中指定 公司setting.xml后,所有的文件都提示找不到 解决办法:把公司se ...

  5. 在VMMap中跟踪不可用的虚拟内存

    VMMap是一个很好的系统内部工具,它可以可视化特定进程的虚拟内存,并帮助理解内存的用途.它有线程堆栈.映像.Win32堆和GC堆的特定报告.有时,VMMap会报告不可用的虚拟内存,这与可用内存不同. ...

  6. Generating YouTube-like IDs in Postgres using PL/V8 and Hashids

    转自:https://blog.abevoelker.com/2017-01-03/generating-youtube-like-ids-in-postgres-using-plv8-and-has ...

  7. contest5 CF991 div2 ooooxx ooooox ooooox

    题意 div2D 给出一个棋盘, 有一些点不能放, 总共\(2\)排, 长度\(n(\le 100)\) 在上面空位摆放\('L'\)字形的牌, 问最多能放几个 例如: 00X00X0XXX0 0XX ...

  8. 第10组 Beta版本演示

    一.小组信息 组长博客链接 组名:凹秃曼 组内成员 学号 组员 031702240 童景霖(组长) 031702225 叶泽林 031702246 陈鸿立 031702201 万本琳 03170222 ...

  9. CF 494E Sharti

    CF 494E Sharti 题意:一个\(n \times n\)的棋盘,共有m个矩形中的格子为白色.两个人需要博弈,每次操作选择一个边长不超过k的正方形并翻转颜色,每次翻转需要正方形的右下角为白色 ...

  10. UDF——文件编码造成UDF编译失败

    有时候我们觉得我们的代码写得很正确的,但是在Fluent当中编译的时候一直编译不通过,提示我们错误,我们根据Fluent当中的错误提示去找到源代码中对应的行,却发现没有错误提示当中的问题,出现这个问题 ...