原题目

Problem Description
A histogram is a polygon composed of a sequence of rectangles aligned at a common base line. The rectangles have equal widths but may have different heights. For example, the figure on the left shows the histogram that consists of rectangles with the heights 2, 1, 4, 5, 1, 3, 3, measured in units where 1 is the width of the rectangles:
Usually, histograms are used to represent discrete distributions, e.g., the frequencies of characters in texts. Note that the order of the rectangles, i.e., their heights, is important. Calculate the area of the largest rectangle in a histogram that is aligned at the common base line, too. The figure on the right shows the largest aligned rectangle for the depicted histogram.

Input
The input contains several test cases. Each test case describes a histogram and starts with an integer n, denoting the number of rectangles it is composed of. You may assume that 1 <= n <= 100000. Then follow n integers h1, …, hn, where 0 <= hi <= 1000000000. These numbers denote the heights of the rectangles of the histogram in left-to-right order. The width of each rectangle is 1. A zero follows the input for the last test case.

Output
For each test case output on a single line the area of the largest rectangle in the specified histogram. Remember that this rectangle must be aligned at the common base line.

Sample Input
7 2 1 4 5 1 3 3
4 1000 1000 1000 1000
0

Sample Output
8
4000

===========================================================

题目大意

题目有多组数据,给出一连串的矩形高度,单个矩形默认宽度为1,高度可变且高度随机。求出这一连串按输入顺序排列的矩形在它们所能够组成的矩形块中最大的矩形面积

解题思路

可用通过维护一个单调递增的单调栈来求出最大矩形面积
假设输入一串矩形高度,分别为:2 4 5 6 3

  1. 首先把所有矩形的高度和下标存在一个结构体数组中
  2. 接着是一个for循环遍历上一步存的矩形数据(关键:①首先判断栈是否为空,主要是方便第一个数据的压栈,第一个数据和后面的数据要区分开;②如果当前的矩形高度比栈顶的矩形高度高,则压栈→维护单调递增的序列,实际上维护单调不减的栈也是可行的;③若当前矩形高度比栈顶高度要低,此时开始while循环pop栈顶元素,直到栈顶元素小于当前矩形高度,然后将当前矩形高度压栈;若当前矩形高度比栈顶高度高,则直接压栈。每pop一次都要计算一次最大矩形面积,用一个变量来记录,下面会模拟循环过程。
  3. 有一种特殊情况为一串连续不减的高度,此时不经过for循环内的while来pop栈顶的过程→栈内会存入所有的矩形高度,所以,在上一步的for循环外,还需要再增设一个循环来清空栈内元素,注意最终栈内元素个数为0。跟上一步第三点while循环类似。下面模拟循环。

===========================================================

首先构建一个结构体数组 temp[max](这里max自己赋值)

struct node
{int height, index;
}temp[max];

增设一个记录最大矩形面积的变量 max_square
声明一个栈的变量 stack< struct node > s

第一步,将所有数据存入temp[max]={ 2, 4, 5, 6, 3, …}

第二步,for循环遍历 temp[max] 中所有的数据(这里假设从下标0开始存入数据);
★ 要对第一个数据进行特殊判断→直接存入,并且需要初始化 max_square = temp[0].height;
★ while 循环判断 当中 n 变量为每组矩形的个数:

for(int i = 0; i < n; i++)
{if(s.empty()){s.push(temp[i]);max_square = temp[i].height;//先默认最大矩形面积为第一个面积continue;}while(!s.empty() && s.top() > temp[i].height)//栈不空时,判断栈顶矩形高度是否比当前矩形高度高。{//如果高于当前矩形高度,则进入while循环进行pop操作,以维护一个单调不减的序列//像2 4 5 6 3这个数据,一直到3才会进入while循环。只要栈内不空并且一直遇到高于3的高度的矩形,那么就要弹出栈顶元素,并且计算一次矩形面积,对比一次最大值。int h = s.top().height;s.pop();if(s.empty())max_square = max(max_square, h * (i - 1));else//pop后栈内存在元素的话,则执行这一个操作max_square = max(max_square, h * (i - 1 - s.top().index));//注意这里的s.top().index不是与当前矩形temp[i]相邻的那个,因为与temp[i]相邻的矩形已经在上面的指令中pop掉了}s.push(temp[i]);//每个矩形都要经历压栈的过程,只要temp[i]不比栈顶矩形高度高,就可以直接压栈。
}

2 4 5 6 一直递增,所以一直没有进入while循环,直到遇到了3,比6小,进入while循环内
此时将高度为 6 的矩形高度暂存入一个变量 h 中,可以发现此时栈内不空,所以进入else下面的指令。已知当前max_square = 2。
矩形面积等于高度成宽度,即height * 1(题目默认每个举行宽度为1),当前 3 的下标为 4,即 i = 4,栈顶矩形高度为 6,下标为 3。
现在想计算出从 2 ~ 6 能构成的最大的矩形的面积,所以要从 6 开始,从右往左扩展矩形面积,并且每轮循环更新一次 max_square。

① i = 4
栈 s [ 2, 4, 5, 6 ]
h = s.top().height = 6 > 3
s.pop()
栈 s [ 2, 4, 5 ]
s.empty() = false
max_square = 2
max_square = max(max_square, h * (i - 1 - s.top().index))
= max(2, 6 * (4 - 1 - 2)) = 6 //因为上面已经将6弹出,所以这次取到的栈顶元素的下标为2,即高度为 5 的矩形的下标。

② 因为栈仍然非空,并且 s.top().height > temp[i] 所以仍然在while循环内,i 不更新。
→ i = 4
栈 s [ 2, 4, 5 ]
h = s.top().height = 5 > 3
s.pop()
栈 s [ 2, 4 ]
s.empty() = false
max_square = 6
max_square = max(max_square, h * (i - 1 - s.top().index))
= max(6, 5 * (4 - 1 - 1)) = 10 //因为上面已经将5弹出,所以这次取到的栈顶元素的下标为1,即高度为 4 的矩形的下标。
此时计算的为这块矩形的面积

③ 因为栈仍然非空,并且 s.top().height > temp[i] 所以仍然在while循环内,i 不更新。
→ i = 4
栈 s [ 2, 4 ]
h = s.top().height = 4 > 3
s.pop()
栈 s [ 2 ]
s.empty() = false
max_square = 10
max_square = max(max_square, h * (i - 1 - s.top().index))
= max(10, 4 * (4 - 1 - 0)) = 12 //因为上面已经将4弹出,所以这次取到的栈顶元素的下标为0,即高度为 2 的矩形的下标。
此时计算的为这块矩形的面积

④ 可以发现,栈 s[ 2 ],s.top().height < temp[i] = 3
此时跳出while循环并且执行s.push(temp[i]),栈 s[ 2, 3 ]。
这次就进入了我们上面所说的为防止栈内仍然存在元素但跳出while循环的备用循环
代码跟上面的while循环差不多。
最后两次循环求的矩形面积为下面两张图片
)

while (!s.empty())
{int h = s.top().height;s.pop();if (s.empty())max_square = max(max_square, h * n);elsemax_square = max(max_square, h * (now_index - s.top().index));
}

有很多种方法,只讲单调栈的解题思路,剩下的处理都比较简单,不需要单独解释了,代码还是要靠自己写出来才会印象深刻。

完整代码

#include <bits/stdc++.h>
#include <algorithm>using namespace std;struct sair {int height, index;
} temp[100005];int main() {int n;while (cin >> n) {if (!n)break;for (int i = 1; i <= n; i++) {cin >> temp[i].height;temp[i].index = i;}stack<sair> s;long long max_square = 0;long long h, index;for (int i = 1; i <= n; i++) {if (s.empty()) {s.push(temp[i]);max_square = temp[i].height;//先默认最大矩形面积为第一个面积continue;}while (!s.empty() && s.top().height > temp[i].height) {//栈不空时,判断栈顶矩形高度是否比当前矩形高度高。//如果高于当前矩形高度,则进入while循环进行pop操作,以维护一个单调不减的序列//像2 4 5 6 3这个数据,一直到3才会进入while循环。只要栈内不空并且一直遇到高于3的高度的矩形,那么就要弹出栈顶元素,并且计算一次矩形面积,对比一次最大值。h = s.top().height;index = s.top().index;s.pop();if (s.empty())max_square = max(max_square, h * (i - 1));else//pop后栈内存在元素的话,则执行这一个操作max_square = max(max_square, h * (i - 1 - s.top().index));//注意这里的s.top().index不是与当前矩形temp[i]相邻的那个,因为与temp[i]相邻的矩形已经在上面的指令中pop掉了}s.push(temp[i]);//每个矩形都要经历压栈的过程,只要temp[i]不比栈顶矩形高度高,就可以直接压栈。}int now_index;if (!s.empty())now_index = s.top().index;while (!s.empty()) {h = s.top().height;index = s.top().index;s.pop();if (s.empty())max_square = max(max_square, h * n);elsemax_square = max(max_square, h * (now_index - s.top().index));}cout << max_square << endl;}return 0;
}

Largest Rectangle in a Histogram HDU - 1506 解题思路 单调栈相关推荐

  1. POJ - 2559 Largest Rectangle in a Histogram(笛卡尔树,单调栈实现)

    题目链接:点击查看 题目大意:给出一排高度不同,宽度都为 1 的矩形,问拼起来后最大的矩形面积是多少 题目分析:普通做法是用单调栈直接维护,我一直觉得单调栈处理这种矩形问题都比较抽象,也可能是我太菜了 ...

  2. hdu 1506(dp || 单调栈)

    题意:这题是要找最大的矩形面积. 解题思路:这题的关键是要找每个条形能够往左和往右能够到达的最大长度.我最开始的思路是单调栈去维护,只要入栈的元素比栈顶元素小,栈顶就要出栈,并且知道其最右能够到达的最 ...

  3. hdu 1506 Largest Rectangle in a Histogram 最大矩形

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=1506 Largest Rectangle in a Histogram Time Limit: 20 ...

  4. *【HDU - 1506】【POJ - 2559】Largest Rectangle in a Histogram(单调栈或动态规划)

    题干: Description A histogram is a polygon composed of a sequence of rectangles aligned at a common ba ...

  5. HDU 1506 Largest Rectangle in a Histogram(dp、单调栈)

    你是不是飘了?骚年! Problem Description A histogram is a polygon composed of a sequence of rectangles aligned ...

  6. 【单调栈】Largest Rectangle in a Histogram(luogu-SP1805/poj 2559)

    Largest Rectangle in a Histogram luogu-SP1805 poj 2559 题目大意: 有n个并排的矩阵,高度为aia_iai​,宽度为1,现在让求包含于这些矩阵的并 ...

  7. poj 2559 Largest Rectangle in a Histogram 栈

    // poj 2559 Largest Rectangle in a Histogram 栈 // // n个矩形排在一块,不同的高度,让你求最大的矩形的面积(矩形紧挨在一起) // // 这道题用的 ...

  8. Largest Rectangle in a Histogram (动态规划+奇思妙想单调栈)求最大矩状图面积

    感觉动态规划都是玄妙的很,思维题吧(单调栈思维) 题解:让求最大矩形面积,宽为1,暴力超时 可以发现   当第i-1个比第i个高的时候   比第i-1个高的所有也一定比第i个高 于是可以用到动态规划的 ...

  9. 【Python CheckiO 题解】Largest Rectangle in a Histogram

    CheckiO 是面向初学者和高级程序员的编码游戏,使用 Python 和 JavaScript 解决棘手的挑战和有趣的任务,从而提高你的编码技能,本博客主要记录自己用 Python 在闯关时的做题思 ...

最新文章

  1. 用Python写出Gameboy模拟器,还能训练AI模型:丹麦小哥的大学项目火了
  2. 不同工作组能访问吗_“辣椒”的辣味从哪里来?有方法能测量不同辣椒的辣度吗?...
  3. Linux系统编程(九)线程同步
  4. mysql更改表 值_如何更改MySQL表中行实例的值?
  5. linux gcc编译下的文件读写操作
  6. 可行后继路由,可行条件和报告距离
  7. python time sleep 阻塞 异步_Python Tornado异步请求被阻塞
  8. atitit agt sys 设置下级代理功能设计.docx
  9. 哪种工业仓库扫描枪适合您?
  10. 高级计算机图形学建模技术与方法
  11. Nginx 企业级优化
  12. 基于STM32单片机的智能药盒带语音播报原理图程序
  13. 如何在CSDN删除自己上传的资源
  14. MyBatis-Spring(五)--MapperScannerConfigurer实现增删改查
  15. #1.从学生表中查询所有学生的所有信息SELECT * FROM `student`#2.从学生表查询所有学生的学号姓名信息并分别赋予别名SELECT StudentNo AS ‘学号‘, St
  16. 图像互信息(MI)的计算(Python版本)
  17. DCGAN生成动漫头像(附代码)
  18. C++ QT Bejeweled宝石迷阵 期末项目
  19. 上海无居住证120积分随迁子女如何求学(中考)
  20. STM32三条总线(AHB、APB1、APB2)的外设映射情况

热门文章

  1. 那天我看着一群老炮怒放 -- zhangchu
  2. DBSCAN-SWA:一行命令找到溶源噬菌体
  3. DXT 图片压缩(DXTC/DirectX Texture Compression Overview)
  4. 基于windriver开发驱动,64位平台和32位平台一次解决
  5. VVC代码阅读 xCheckModeSplit()函数 (中间CABAC还没看)最后代码还没看完
  6. 基于WASM的H265 Web播放器
  7. Android中的ping网络实现
  8. linux游戏龙芯能玩吗,历时三个月,我终于成功搭建了龙芯平台,竟可以玩cf和lol你敢信?...
  9. 算法分析与设计:贪心算法实现最少硬币找钱问题(支付+找零共花费硬币数最少)
  10. “互联网+”催生农产品线交易万亿市场