题干:

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

解题报告:

单调栈模板!此题用动态规划亦可解。题目大意就是求矩形的可最大面积

ac代码1:(因为第一次用单调栈所以代码十分丑陋、、、)

#include<bits/stdc++.h>#define ll long longusing namespace std;
const int MAX = 100000 + 5 ;
const int INF = 0x3f3f3f3f;
int top;
stack <ll> sk,sk2;
ll a[MAX];
ll zuo[MAX],you[MAX];
ll maxx;
int main()
{int n;while(scanf("%d",&n) ) {if( n==0 ) break;maxx=0;while(!sk.empty() ) sk.pop();while(!sk2.empty() ) sk2.pop();top = -1;for(int i = 0; i<n; i++) {scanf("%lld",&a[i]);}//递增栈 找左侧的最小元素 sk.push(0);zuo[0]=-1;for(int i = 1; i<n; i++) {if(sk.empty() ) {zuo[i]=-1;sk.push(i);}else {while(!sk.empty() && a[sk.top()]>=a[i] ) {sk.pop();}if(sk.empty() ) {zuo[i]=-1;sk.push(i);}else {zuo[i]=sk.top();sk.push(i);}}}sk2.push(n-1);you[n-1]=n;for(int i = n-2; i>=0; i--) {if(sk2.empty() ) {you[i]=n;sk2.push(i);}else {while(!sk2.empty() && a[sk2.top()]>=a[i] ) {sk2.pop();}if(sk2.empty() ) {you[i]=n;sk2.push(i);}else {you[i]=sk2.top();sk2.push(i);}}}for(int i = 0; i<n; i++) {maxx=max(maxx,a[i]*(you[i]-zuo[i]-1) );}printf("%lld\n",maxx);}return 0 ;
}

ac代码2:(动态规划)

如果确定了长方形的左端点L和右端点R,那么最大可能的高度就是min{hi|L <= i < R}。

L[i] = (j <= i并且h[j-1] < h[i]的最大的j)

R[i] = (j > i并且h[j] > h[i]的最小的j)

#include <stdio.h>#define MAX_N 100000int n;
int h[MAX_N];
int L[MAX_N], R[MAX_N];
int stack[MAX_N];long long max(long long a, long long b){return (a > b) ? a : b;
}void solve(){//计算Llong long ans = 0;int t = 0;int i;for (i = 0; i < n; ++i){while (t > 0 && h[stack[t-1]] >= h[i]) t--;L[i] = (t == 0) ? 0 : (stack[t-1] + 1);stack[t++] = i;}//计算Rt = 0;for (i = n - 1; i >= 0; --i){while (t > 0 && h[stack[t-1]] >= h[i]) t--;R[i] = (t == 0) ? n : stack[t-1];stack[t++] = i;}for (i = 0; i < n; ++i){ans = max(ans, (long long)h[i] * (R[i] - L[i]));}printf("%lld\n", ans);
}int main(void){int i;while (scanf("%d", &n) != EOF && n != 0){for (i = 0; i < n; ++i)scanf("%d", &h[i]);solve();}return 0;
}

ac代码3:(动态规划)

/*
每一个图形都有一个h[i],l[i],r[i]!其中l[i]存的是左数至少比他高的图形的序数,r[i]存的是右数至少比他高的图形的序数!
剪枝 while(h[r[i]+1]>=h[i]) {r[i]=r[r[i]+1];}特别重要!看右面有没有比他大的,
有就看右面那个r[]存的序数是多少,一步一步最终找到连续的长方形!
*/
#include<cstdio>
#include<iostream>
const int N=110000;
using namespace std;
long long h[N],l[N],r[N];
int main()
{long long n;int i;while(scanf("%lld",&n)&&n){for(i=1;i<=n;i++){scanf("%lld",&h[i]);l[i]=r[i]=i;}h[0]=h[n+1]=-1;for(i=1;i<=n;i++){while(h[l[i]-1]>=h[i]){l[i]=l[l[i]-1];//这个体现动态规划的思想,存l[l[i]-1]而不是l[i]-1}//这样就可以节省其中很多的步骤!根据动态规划原理这一找}for(i=n;i>=1;i--){while(h[r[i]+1]>=h[i]){r[i]=r[r[i]+1];}}long long maxs=-5,flag;for(i=1;i<=n;i++){flag=(r[i]-l[i]+1)*h[i];if(flag>maxs){maxs=flag;}}printf("%lld\n",maxs);}
}

ac代码4:(单调栈模板)

#include<bits/stdc++.h>using namespace std;typedef long long ll;
const int N = 100000 + 100;stack<int> S;
ll h[N];
int R[N],L[N];int main(){int n;while(~scanf("%d",&n) && n){for(int i=0 ;i<n ;i++)  scanf("%I64d",&h[i]);while(S.size()) S.pop();for(int i=0 ;i<n ;i++){while(S.size() && h[S.top()] >= h[i]) S.pop();if(S.empty())     L[i] = 0;else              L[i] = S.top() + 1;S.push(i);}while(S.size()) S.pop();for(int i=n-1 ;i>=0 ;i--){while(S.size() && h[S.top()] >= h[i]) S.pop();if(S.empty()) R[i] = n;else          R[i] = S.top();S.push(i);}ll ans = 0;for(int i=0 ;i<n ;i++){ans = max(ans,h[i] * (R[i] - L[i]));}printf("%I64d\n",ans);}return 0;
}

总结:

1.单调栈的题 读数最好从1开始,不然就会出现ac代码4中S.top()+1这种不优雅的情况。

2.就算你是从0开始读的,但如果没有比L(i)小的,也要赋值坐标成0!因为你如果左边单调栈一次,右边单调栈一次,最后算差值的时候还要再-1(比如ac代码1),也会不美观。

3.综上所述,还是从i=1开始读比较好。。

4.注意数据是需要longlong的!!

5.下附单调栈模板(核心):

for(int i=1 ;i<=n ;i++){while(S.size() && h[S.top()] >= h[i]) S.pop();if(S.empty())     L[i] = 0;else              L[i] = S.top();S.push(i);}

6.对上述模板有两个地方是可以更改的,一个是   h[S.top()] >= h[i]   的等于号,另一个是栈中存的数据,有时是存下标(位置),如此题,还有的情况是存值。这一点依题目情况而定。

*【HDU - 1506】【POJ - 2559】Largest Rectangle in a Histogram(单调栈或动态规划)相关推荐

  1. poj 2559 Largest Rectangle in a Histogram 栈

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

  2. HDU 1506 解题报告 Largest Rectangle in a Histogram (单调栈)

    看题传送门:http://acm.hdu.edu.cn/showproblem.php?pid=1506 题意比较明显,就是找以某一个矩形为高的最大的矩形.这个题可以用单调栈来求解,需要注意的是如果从 ...

  3. POJ2559 Largest Rectangle in a Histogram(单调栈)

    题意: 给出一组矩形的高,求最多能拼成矩形的最大面积,看图就很清楚了. 要点: 还是单调栈,现在有点感觉了,单调栈大概就是能求出当前值左右的比它大或小的数的范围.这题用高度作为单调栈,分别往左右找比当 ...

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

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

  5. POJ - 2559 Largest Rectangle in a Histogram(单调栈)

    题意:有n个高度不同的直方图,求直方图内最大的矩形面积. 分析: 1.若当前研究高度大于栈顶高度,则直接入栈.否则,边处理栈内所有高度大于等于当前高度的元素边出栈,在此过程中,边累加宽度边以当前栈顶元 ...

  6. ACM PKU 2559 Largest Rectangle in a Histogram http://acm.pku.edu.cn/JudgeOnline/problem?id=2559

    关于覆盖,用DP是一种很不错的解决方法,时效也很不错.... 这题目把图一画就很明确了,没有说明的必要了. #include <iostream> using namespace std; ...

  7. HDU1506 / POJ2339 Largest Rectangle in a Histogram 单调递减栈

    1.什么是单调栈 具有单调性和栈的性质 单调递减栈就是从栈底到栈顶是单调递减的 单调递增栈就是从栈底到栈顶是单调递增的 2.单调栈解决的问题 以自己为最小值,找到最长的区间:单调递增栈 以自己为最大值 ...

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

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

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

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

最新文章

  1. Linux的rc.local自启动服务
  2. 03-2 BGP专有命令--BGP命令与配置手册
  3. 面向对象程序设计第二次作业
  4. 【Linux 内核】CFS 调度器 ④ ( 调度子系统组件模块 | 主调度器、周期性调度器 | 调度器类 )
  5. MATLAB从入门到精通-辅助ANSYS APDL进行负泊松比铰链结构建模仿真(附源码)
  6. 数据对比国内外电影票房,国产剧差在哪?
  7. pgsql数据库默认配置事务类型_postgreSql最佳配置详解(connection 申请、回收策略)...
  8. keil C对lib封装库反汇编成C语言,Keil软件“C语言”及“汇编”混编 —— 相关知识整理.doc...
  9. linux rpm 查找,Linux下 rpm 命令查询方法
  10. 面试问题_教资面试,结构化面试问题分享
  11. java int a=b指向_java里int a=3,给a赋值的时候,是给它3的地址,还是直接赋值二进制3?...
  12. Spark创建临时视图
  13. Python捕捉命令输出、错误输出及赋值命令到变量的方法
  14. todo elk搭建日志系统
  15. 读书篇:《细说PHP》三、PHP的语言结构
  16. 基本图像分类与目标检测网络要点总结
  17. 使用enum代替Constants
  18. 音乐现场的未来将被NFT门票主宰?
  19. 【福利分享】java书籍推荐!
  20. 请导入ce12800的设备包_CE1280012800E堆叠部署示例

热门文章

  1. [周赛][Leetcode][第5457题][JAVA][动态规划][和为奇数的子数组数目]
  2. PAT 1009 说反话
  3. python提取网页中p标签中的内容_使用Python进行爬虫的初学者指南
  4. 和县机电工程学校工业机器人_【校企合作】学校举行工业机器人教学系统捐赠仪式...
  5. VSCODE修改文字编码格式为GB2312和TAB键为2个空格(MDK5和VSCODE联合开发STM32程序)
  6. python数据预处理_Python数据预处理——缺失值、重复值
  7. UE4 Fix – “Lighting build failed. Swarm failed to kick off.”
  8. cc、gcc、g++、CC的区别概括
  9. Socket的send函数在执行时报EAGAIN的错误
  10. 用VS2005开发WinCE程序调试图文教程