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. nginx配置https并强制http自动跳转到https

    关于使用HTTPS/SSL的必要性,可以自行baidu,援引的说法,EFF(Electronic Frontier Foundation),全球过半流量采用https. https://www.osc ...

  2. 03:requests与BeautifulSoup结合爬取网页数据应用

    1.1 爬虫相关模块命令回顾 1.requests模块 1. pip install requests 2. response = requests.get('http://www.baidu.com ...

  3. 03: KindEditor (HTML可视化编辑器)

    目录: 1.1 kindEditor常用配置参数 1.2 kindEditor下载与文件说明 1.3 kindEditor实现上传图片.文件.及文件空间管理 1.1 kindEditor常用配置参数返 ...

  4. Ubuntu Linux系统环境变量配置文件

    Ubuntu Linux系统环境变量配置文件: /etc/profile : 在登录时,操作系统定制用户环境时使用的第一个文件 ,此文件为系统的每个用户设置环境信息,当用户第一次登录时,该文件被执行. ...

  5. 文件IO和标准IO的区别【转】

    一.先来了解下什么是文件I/O和标准I/O: 文件I/O:文件I/O称之为不带缓存的IO(unbuffered I/O).不带缓存指的是每个read,write都调用内核中的一个系统调用.也就是一般所 ...

  6. P2709 小B的询问

    题目描述 小B有一个序列,包含N个1~K之间的整数.他一共有M个询问,每个询问给定一个区间[L..R],求Sigma(c(i)^2)的值,其中i的值从1到K,其中c(i)表示数字i在[L..R]中的重 ...

  7. Linq 对List的一些操作

    代码: public class Person { public int ID { get; set; } public string Name { get; set; } public int Ag ...

  8. java Request 获得用户IP地址

    public static String getIpAddress(HttpServletRequest request) { String ip = request.getHeader(" ...

  9. C# 给某个方法设定执行超时时间

    ManualResetEvent.WaitOne 方法 https://msdn.microsoft.com/en-us/library/system.threading.manualreseteve ...

  10. Java Collections Framework概览

    本文github地址 概览 容器,就是可以容纳其他Java对象的对象.Java Collections Framework(JCF)为Java开发者提供了通用的容器,其始于JDK 1.2,优点是: 降 ...