*【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 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]   的等于号,另一个是栈中存的数据,有时是存下标(位置),如此题,还有的情况是存值。这一点依题目情况而定。

 

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/442085.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【基础知识】大数据组件HBase简述

HBase是一个开源的、面向列&#xff08;Column-Oriented&#xff09;、适合存储海量非结构化数据或半结构化数据的、具备高可靠性、高性能、可灵活扩展伸缩的、支持实时数据读写的分布式存储系统。 只是面向列&#xff0c;不是列式存储 mysql vs hbase vs clickhouse HMaster …

改变定时器获取传感器频度_广东梅州梅县压力传感器*校对

广东梅州梅县压力传感器*校对看门狗寄存器不会改变或改变不大&#xff0c;如果看门狗寄存器发生了改变或改变很大&#xff0c;则说明系统陷入“死循环”.需要进行出错处理。在工业应用中&#xff0c;严重的干扰有时会破坏中断方式控制字&#xff0c;关闭中断&#xff0c;造成看…

springboot 不响应字段为空_面试官扎心一问:Tomcat 在 SpringBoot 中是如何启动的?...

作者&#xff1a;木木匠 http://my.oschina.net/luozhou/blog/3088908前言我们知道 SpringBoot 给我们带来了一个全新的开发体验&#xff0c;我们可以直接把 web 程序达成 jar 包&#xff0c;直接启动&#xff0c;这就得益于 SpringBoot 内置了容器&#xff0c;可以直接启动&am…

a1708硬盘转接口_资讯:希捷上架新款银河Exos系列机械硬盘,15000转+SAS协议

今日最新消息&#xff0c;希捷上架一款新品希捷银河Exos系列机械硬盘。据悉这款硬盘采用了SAS协议&#xff0c;转速高达15000RPM&#xff0c;目前公布的售价600GB为1899元RMB。据官方介绍这款希捷银河Exos系列机械硬盘为2.5英寸&#xff0c;15mm的厚度&#xff0c;最高的转速可…

腐蚀单机怎么进_暖气片堵塞是什么原因?要怎么解决呢?

你知道散热器到底为什么堵塞吗&#xff1f;散热器堵塞了怎么办&#xff1f;下面和金旗舰散热器小编一起来看看吧~一、散热器堵塞怎么办首先&#xff0c;把进回水阀先全部关闭&#xff0c;用扳手将散热器的堵头轻轻拧开。这里需要注意的是&#xff0c;堵头对应的散热器下面要放一…

vspy如何在图形面板显示报文_设备实时状态监控:如何进行工业生产设备数据采集?...

设备实时状态监控&#xff1a;如何进行工业生产设备数据采集&#xff1f;数据采集(DAQ)&#xff0c;是指从传感器和其它待测设备等模拟和数字被测单元中自动采集非电量或者电量信号,送到上位机中进行分析&#xff0c;处理。慧都设备数据采集系统解决方案工业生产设备数据采集是…

Sql Server数据库设置一个账户只能看到一个数据库

1 新建登录名&#xff0c;注意不要设置用户映射&#xff0c;服务器角色只选择public&#xff08;默认必选&#xff0c;无法去掉&#xff0c;可以添加其他服务器角色&#xff0c;但是不要添加查看所有数据库的权限&#xff0c;接下来会去掉public的查看所有数据库权限&#xff0…

如何在修改计算机设置时,不再弹出提示框?

1 打开控制面板&#xff0c;找到安全与维护&#xff1b; 2 进入安全与维护&#xff0c;在安全中找到“用户账户控制UAC”&#xff0c;点击打开“更改设置” 3 进行设置&#xff0c;“从不通知”设置之后&#xff0c;针对计算机的所有更改将不再提示

matlab两张图片合成一张_11. 图像合成与图像融合

本文同步发表在我的微信公众号“计算摄影学”&#xff0c;欢迎扫码关注【转载请注明来源和作者】我们终于进入了新的篇章。这一次我来给大家介绍一下图像合成与融合。我们经常看到一些很奇妙的PS技术&#xff0c;例如下面这张&#xff0c;它把1928年的一位叫做Frankie Yale的黑…

于小c三国语言_云顶之弈:三国成最强打工羁绊 校长教学顺滑转九五

虎牙校长是九五阵容的专业户&#xff0c;虽然版本在不断地更新&#xff0c;云顶的整体走向也在不断地发生变化&#xff0c;但九五至尊的强度一直都是TOP0级别&#xff0c;一旦成型第四保底&#xff0c;吃鸡都变得轻而易举。而整套九五的运营关键在于如何连胜、保证自身血量健康…

java null转换jason_常见java问题及解决办法汇总(干货可收藏)

Java Exception&#xff1a;1、Error2、Runtime Exception 运行时异常3、Exception4、throw 用户自定义异常异常类分两大类型&#xff1a;Error类代表了编译和系统的错误&#xff0c;不允许捕获&#xff1b;Exception类代表了标准Java库方法所激发的异常。Exception类还包含运行…

【HDU - 3038】How Many Answers Are Wrong (带权并查集--权为区间和)

题干&#xff1a;&#xff08;&#xff09; TT and FF are ... friends. Uh... very very good friends -________-b FF is a bad boy, he is always wooing TT to play the following game with him. This is a very humdrum game. To begin with, TT should write down a s…

drop sqlite 多个表_SQLite简介与安装

SQLite简介&#xff1a;SQLite是一款轻型的数据库&#xff0c;是遵守ACID的关系型数据库管理系统&#xff0c;它包含在一个相对小的C库中&#xff0c;实现了自给自足的、无服务器的、零配置的、事务性的 SQL 数据库引擎。就像其他数据库&#xff0c;SQLite 引擎不是一个独立的进…

【CF566#D】 Restructuring Company (并查集---合并区间操作)

题干&#xff1a; Even the most successful company can go through a crisis period when you have to make a hard decision — to restructure, discard and merge departments, fire employees and do other unpleasant stuff. Lets consider the following model of a c…

dg oracle 切换模式_谈谈dg切换涉及的概念:switchover和failover区别

概述今天有朋友问了一个问题&#xff1a;switchover和failover之间的区别&#xff0c;有点懵逼&#xff0c;居然把这忘记了&#xff0c;这里总结下两者之间的一些区别。DG架构DG切换时注意点&#xff1a;1、确认主库和从库间网络连接通畅&#xff1b;2、确认没有活动的会话连接…

gis影像格式img转为ecw_医学影像图片格式

&#xff08;1&#xff09;Analyze格式&#xff1a;Analyze格式储存的每组数据组包含2个文件&#xff0c;一个为数据文件&#xff0c;其扩展名为.img&#xff0c;包含二进制的图像资料&#xff1b;另外一个为头文件&#xff0c;扩展名为.hdr&#xff0c;包含图像的元数据。&…

case when then else多个条件_sqlserver条件分支case when使用教程

在sqlserver的条件分支case when有两种写法&#xff1a;1)case 字段 when 值 then 返回值 when 值2 then 返回值2 end2)case when 条件1 then 返回值1 when 条件2 then 返回值2 end方法步骤&#xff1a;1.打开“SQL Server Management Studio”管理工具&#xff0c;创建一张测试…

hashmap value占用空间大小_【Java集合框架002】原理层面:HashMap全解析

一、前言二、HashMap2.1 HashMap数据结构 HashMap线程不安全 哈希冲突2.1.1 HashMap数据结构学习的时候&#xff0c;先整体后细节&#xff0c;HashMap整体结构是 底层数组链表 &#xff0c;先记住&#xff0c;再开始看下面的HashMap相关知识点&#xff1a;底层数据结构&#…

升级bios_华硕B350PLUS升级BIOS更换AMD 3900X步骤

首先CPU更换看下面这张图&#xff0c;注意CPU上的小三角的位置。这块主板如果BIOS没有升级直接更换AMD 3900X的CPU会有点不亮显示器的问题&#xff0c;所以下面讲下华硕B350PLUS这块主板是如何更新到最新的BIOS驱动的(需要在原来老的CPU基础上先升级&#xff0c;升级完再更换39…

实体类 接口_spring-boot-route(五)整合Swagger生成接口文档

目前&#xff0c;大多数公司都采用了前后端分离的开发模式&#xff0c;为了解决前后端人员的沟通问题&#xff0c;后端人员在开发接口的时候会选择使用swagger2来生成对应的接口文档&#xff0c;swagger2提供了强大的页面调试功能&#xff0c;这样可以有效解决前后端人员沟通难…