Largest Rectangle in a Histogram

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 18065    Accepted Submission(s):
5394

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
 
Source
首先吐槽自己手贱非得开ULL导致后面查BUG查了半天mdzz!
纯无思路~~后来扫一眼别人的某片代码(好吧以后不看题解了)
可还是搞了半天,一开始总是想直接一遍DP过去找到最大值,可是发现不行啊,例如(121),(212)这种数据处理起来好麻烦哇!
从大方向出发,找最优解具有的特征,首先最优矩形的高度一定是与给出的某个木板的高度平行的,由贪心理论 可证得,假设存在一个最优解不满足这个条件,显然还可以把他的高度继续往上增加;
所以从这一点出发,得出结论,最优解是由某一个木板,从这个高度出发,无限往左右延伸直至无法延伸而得到的一个矩形!
之所以不能是某个高度无限往左/右某个单一方向延伸得到是因为如果存在凹形数据(212)的话显然这样的方法就失效了,正确答案是3,可是单一方向计算的话只能得出2.
接着就是利用lef和rig数组计算的出,lef[i]:第i块木板往左最长延伸到第几块木板,rig同理不再赘述。
(错误)计算方法显然是:  
if(h[i]<=h[i-1])   lef[i]=lef[i-1];
else lef[i]=i;
但是仔细想想不难发现错误所在,如果这个h[lef[i-1]-1]的高度大于h[i]但是由于h[lef[i-1]-1]<h[lef[i-1]]的话,无疑这个木板及其前面满足条件的木板都会被漏掉!
举个栗子方便理解(1 2 1 1 1) 这样计算的话lef[]={1,2,2,2,2},显然是错的,第五快木板可以直接连到第一块的位置。
那么修改时难道要从得出的位置开始一个一个往前推吗?这样是对的但是显然(MAX_N=10w)的值不会允许我们这样做的,会导致TLE;
仔细想的话会发现,假设k=lef[i](lef[i]已经经过第一次的计算),如果h[k-1]>=h[i]的话那么h[lef[k-1]]也一定大于等于h[i],这样一直迭代加深的找下去肯定会比朴素的查找更快!
代码:
 

#include<bits/stdc++.h>
using namespace std;
#define ULL long long
#define ql(a) memset(a,0,sizeof(a))
ULL max(ULL a,ULL b){return a>b?a:b;}
ULL h[100005],lef[100005],rig[100005];
int n;
ULL solve()
{h[0]=-99999,h[n+1]=-99999;
ULL maxn=0;
ULL i,j,t;
for( i=1;i<=n;++i){
if(i==1) {lef[i]=i;continue;}
if(h[i]<=h[i-1]) lef[i]=lef[i-1];
else lef[i]=i;
int k=lef[i];
while(h[k-1]>=h[i]) k=lef[k-1];
lef[i]=k;

}
for(i=n;i>=1;--i){
if(i==n) {rig[i]=i;continue;}
if(h[i]<=h[i+1]) rig[i]=rig[i+1];
else rig[i]=i;
int k=rig[i];
while(h[k+1]>=h[i]) k=rig[k+1];
rig[i]=k;
}
for(i=1;i<=n;++i){
if(h[i]*(rig[i]-lef[i]+1)>maxn) maxn=h[i]*(rig[i]-lef[i]+1);
}
return maxn;
}
int main()
{
int i,j;
while(cin>>n&&n){
ULL maxn=0;
for(i=1,j=n;i<=n;++i,--j)
scanf("%lld",&h[i]);
printf("%lld\n",solve());
}
return 0;
}

HDU1506(真心不错的DP)的更多相关文章

  1. HDU1506(单调栈或者DP) 分类: 数据结构 2015-07-07 23:23 2人阅读 评论(0) 收藏

    Largest Rectangle in a Histogram Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 ...

  2. CodeForces - 156C:Cipher (不错的DP)

    Sherlock Holmes found a mysterious correspondence of two VIPs and made up his mind to read it. But t ...

  3. SPOJ:Collecting Candies(不错的DP)

    Jonathan Irvin Gunawan is a very handsome living person. You have to admit it to live in this world. ...

  4. HihoCoder1706 : 末尾有最多0的乘积(还不错的DP)

    描述 给定N个正整数A1, A2, ... AN. 小Hi希望你能从中选出M个整数,使得它们的乘积末尾有最多的0. 输入 第一行包含两个个整数N和M. 第二行包含N个整数A1, A2, ... AN. ...

  5. zookeeper基本讲解(Java版,真心不错)

    1. 概述 Zookeeper是Hadoop的一个子项目,它是分布式系统中的协调系统,可提供的服务主要有:配置服务.名字服务.分布式同步.组服务等. 它有如下的一些特点: 简单 Zookeeper的核 ...

  6. 转 Activity的四种LaunchMode(写的真心不错,建议大家都看看)

      我们今天要讲的是Activity的四种launchMode. launchMode在多个Activity跳转的过程中扮演着重要的角色,它可以决定是否生成新的Activity实例,是否重用已存在的 ...

  7. 这个捕鱼游戏制作的真心不错,原创音乐,AV动作,让人流连忘返啊呵呵

     女生看完这篇文章后果断地命令男朋友打开电脑和手机 2014-10-10 茶娱饭后 本人纯屌丝宅男一名.专注游戏十年有余,玩过无数大大小小的游戏,对捕鱼游戏情有独钟.我不想说在捕鱼游戏方面有多专业 ...

  8. SPOJ:Harbinger vs Sciencepal(分配问题&不错的DP&bitset优化)

    Rainbow 6 is a very popular game in colleges. There are 2 teams, each having some members and the 2 ...

  9. 开发跨平台应用解决方案-uniapp 真心不错,支持一波

    uni-app 是一个使用 Vue.js 开发跨平台应用的前端框架,开发者编写一套代码,可编译到iOS.Android.微信小程序等多个平台. 用了mui,H5+一年多了,感觉dcloud 最近推出的 ...

随机推荐

  1. python之路----常用模块二

    collections模块 在内置数据类型(dict.list.set.tuple)的基础上,collections模块还提供了几个额外的数据类型:Counter.deque.defaultdict. ...

  2. Php cli模式下执行报错/usr/bin/php: /usr/local/lib/libxml2.so.2: no version information available (required by /usr/bin/php)

    centos下php cli模式报错 /usr/bin/php: /usr/local/lib/libxml2.so.2: no version information available (requ ...

  3. Total Difference String

    Total Difference Strings 给一个string列表,判断有多少个不同的string,返回个数相同的定义:字符串长度相等并从左到右,或从右往左是同样的字符 abc 和 cba 为视 ...

  4. 任务调度之Timer与TimerTask配合

    什么是任务调度? 在实际业务中,我们经常需要定时.定期.或者多次完成某些任务,对这些任务进行管理,就是任务调度.任务调度与多线程密切相关. 任务调度有多种方式 Timer与TimerTask配合 Ti ...

  5. ms08_067攻击实验

    ms08_067攻击实验 ip地址 开启msfconsole 使用search ms08_067查看相关信息 使用 show payloads ,确定攻击载荷 选择playoad,并查看相关信息 设置 ...

  6. 如何写出格式优美的javadoc?

    如果你读过Java源码,那你应该已经见到了源码中优美的javadoc.在eclipse 中鼠标指向任何的公有方法都会显示出详细的描述,例如返回值.作用.异常类型等等. 本文主要来自<Thinki ...

  7. arch/manjaro linux configuration

    0. Installation SystemConfiguration: # 启动时选择第二项boot(non-free),Manjaro自带的驱动精灵会帮你安装好所需驱动,笔记本双显卡则会帮你安装b ...

  8. 查找SQL 存储过程、触发器、视图!

    ALTER proc [dbo].[SP_SQL](@ObjectName sysname)  as  set nocount on ;  declare @Print nvarchar(max)-- ...

  9. 抽象类的继承,接口的实现,接口类型数组的使用,根据instanceof判断(返回)是否该是哪一个类型,类型的强转.

    总觉得之前第2处有点问题,果然. 还需要instanceof判定一下,然后还需要把数组Animal[]转为Pet的才有方法play()~~~!

  10. setSupportActionBar()方法报错

    在Android开发中,使用ToolBar控件替代ActionBar控件,需要在java代码中使用setSupportActionBar()方法,如下: Toolbar toolbar = (Tool ...