Largest Rectangle in a Histogram

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

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
 
好爽啊,用RMQ+二分解法AC了,向左边找的死循环真的困扰了我好久。。当然第二种DP解法容易写一点,但是跳跃性的思维比较难想到
解法一:RMQ+二分 时间复杂度:O(n*log(n))
#include<stdio.h>
#include<iostream>
#include<string.h>
#include<math.h>
#include<algorithm>
using namespace std;
const int N = ;
int min_dp[N][];
long long a[N];
int L[N],R[N];
int MIN(int i,int j)
{
if(a[i]>a[j]) return j;
return i;
}
void init_RMQ(int n)
{
for(int i=; i<=n; i++)
{
min_dp[i][]=i;
}
for(int j=; (<<j)<=n; j++)
{
for(int i=; i+(<<j)-<=n; i++)
{
min_dp[i][j] = MIN(min_dp[i][j-],min_dp[i+(<<(j-))][j-]);
}
}
} int MIN_RMQ(int l,int r)
{
int k=;
while((<<(k+))<=(r-l+)) k++;
return MIN(min_dp[l][k],min_dp[r-(<<k)+][k]);
}
int binary(int value,int l,int r) ///找到最右边
{
while(l<=r)
{
if(l==r) return l;
int mid = (l+r)>>;
if(value<=a[MIN_RMQ(l,mid)])
{
l = mid+;
}
else r = mid;
} }
int binary2(int value,int l,int r) ///找到最左边
{
while(l<r)
{
if(l==r-){ ///防止死循环,这里弄了好久
if(a[r]<value) return r; ///如果在r 并且a[r]<value 那么肯定r就是左边界
       return l;
}
int mid = (l+r)>>;
if(value<=a[MIN_RMQ(mid,r)])
{
r = mid-;
}
else l = mid;
}
return l;
}
int main()
{
int n;
while(scanf("%d",&n)!=EOF&&n)
{
for(int i=; i<=n; i++)
{
scanf("%lld",&a[i]);
}
init_RMQ(n);
L[]=;
R[n]=n;
for(int i=; i<=n; i++)
{
if(i!=n)
{
R[i] = binary(a[i],i+,n);
if(R[i]==n&&a[i]<=a[n]);
else R[i]--;
}
if(i!=)
{
L[i] = binary2(a[i],,i-);
if(L[i]==&&a[i]<=a[]);
else L[i]++;
}
}
long long mx = -;
for(int i=; i<=n; i++)
{
if((R[i]-L[i]+)*a[i]>mx) mx = (R[i]-L[i]+)*a[i];
}
printf("%lld\n",mx);
} }

解法二:DP 时间复杂度O(n*k) k是个很小的数

#include <stdio.h>
#include <iostream>
#include <string.h>
#include <math.h>
#include <algorithm>
using namespace std;
const int N = ;
long long a[N],L[N],R[N]; ///L[i]记录i点能够到达最左边的位置,R[i]同理
int main()
{
int n;
while(scanf("%d",&n)!=EOF&&n){
for(int i=;i<=n;i++){
scanf("%lld",&a[i]);
}
L[]=;
R[n]=n;
for(int i=;i<=n;i++){ ///先求出每个坐标最左边能到达的位置
int t = i;
while(t>&&a[i]<=a[t-]){
t = L[t-]; ///这步相当巧妙,直接实现了跳转,如果a[t-1]不小于a[i]
///的话,我们可以断定a[t-1]的最左边肯定包含a[i]的最左边.直接跳过中间的点
///时间复杂度就肯定没有O(n*n)了,应该是O(n*k) k是个比较小的数
}
L[i] = t;
}
for(int i=n-;i>=;i--){ ///找最右边
int t =i;
while(t<n&&a[i]<=a[t+]){
t = R[t+];
}
R[i] = t;
}
long long mx = -;
for(int i=;i<=n;i++){
if((R[i]-L[i]+)*a[i]>mx) mx = (R[i]-L[i]+)*a[i];
}
printf("%lld\n",mx);
}
return ;
}
 

hdu 1506(好题+DP或者RMQ)的更多相关文章

  1. HDU 1506 Largest Rectangle in a Histogram (dp左右处理边界的矩形问题)

    E - Largest Rectangle in a Histogram Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format: ...

  2. HDU 4778 状压DP

    一看就是状压,由于是类似博弈的游戏.游戏里的两人都是绝对聪明,那么先手的选择是能够确定最终局面的. 实际上是枚举最终局面情况,0代表是被Bob拿走的,1为Alice拿走的,当时Alice拿走且满足变换 ...

  3. HDOJ(HDU).2602 Bone Collector (DP 01背包)

    HDOJ(HDU).2602 Bone Collector (DP 01背包) 题意分析 01背包的裸题 #include <iostream> #include <cstdio&g ...

  4. Bomb HDU - 3555 (数位DP)

    Bomb HDU - 3555 (数位DP) The counter-terrorists found a time bomb in the dust. But this time the terro ...

  5. hdu 1505 && hdu1506 &&hdu 2830 && 2870 总结---------DP之状图选最大矩形

    /* 多谢了“闭眼,睁眼” 同学给我一套dp专题,不然真是没接触过这种题型. 做个4个简单的,很高兴有所收获. 2013-08-06 /* HDU 1506 最基础的一道题目,其主要精髓就在于两个数组 ...

  6. HDU 1506 Largest Rectangle in a Histogram set+二分

    Largest Rectangle in a Histogram Problem Description: A histogram is a polygon composed of a sequenc ...

  7. HDU 1011 树形背包(DP) Starship Troopers

    题目链接:  HDU 1011 树形背包(DP) Starship Troopers 题意:  地图中有一些房间, 每个房间有一定的bugs和得到brains的可能性值, 一个人带领m支军队从入口(房 ...

  8. HDU 1950 Bridging signals (DP)

    职务地址:HDU 1950 这题是求最长上升序列,可是普通的最长上升序列求法时间复杂度是O(n*n).显然会超时.于是便学了一种O(n*logn)的方法.也非常好理解. 感觉还用到了一点贪心的思想. ...

  9. hdu 2296 aC自动机+dp(得到价值最大的字符串)

    Ring Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submis ...

随机推荐

  1. bzoj1014: [JSOI2008]火星人prefix(splay+hash+二分)

    题目大意:一个字符串三个操作:①求两个后缀的LCP②插入一个字符③修改一个字符. 前几天刚学了hash+二分求lcp,就看到这题. 原来splay还能这么用?!原来splay模板这么好写?我以前写的s ...

  2. Linux之根文件系统的构建20160611

    说一下LINUX根文件系统的构建: 制作文件系统 1. 交叉编译busybox 安装:make install CONFIG_PREFIX=/work/nfs_root/fs_mini_mdev_ne ...

  3. HDU 2646 栈的应用 STL

    Expression Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total ...

  4. 覆盖的面积 HDU - 1255 (线段树-扫描线)模板提

    给定平面上若干矩形,求出被这些矩形覆盖过至少两次的区域的面积. Input输入数据的第一行是一个正整数T(1<=T<=100),代表测试数据的数量.每个测试数据的第一行是一个正整数N(1& ...

  5. HTMLajax跨域向服务器写入数据

    1.XMLHttpRequest升级版已经实现了跨域请求.不过需要在后台设置:header("Access-Control-Allow-Origin:http://www.a.com&quo ...

  6. 开发系统级应用不被Kill

    一.设置方法 (1) 在AndroidManifest中application根节点下,添加如下代码: android:persistent="true" (2) 将应用程序pus ...

  7. [Spark经验一]Spark RDD计算使用的函数里尽量不要使用全局变量

    比如RDD里的计算调用了别的组件类里的方法(比如hbase里的put方法),那么序列化时,会将该方法所属的对象的所有变量都序列化的,可能有些根本没有实现序列化导致直接报错.也就是spark的api没有 ...

  8. [CodeChef - GERALD07 ] Chef and Graph Queries

    Read problems statements in Mandarin Chineseand Russian. Problem Statement Chef has a undirected gra ...

  9. 关于Redis在Linux手动安装配置

    安装: 1.获取redis资源 wget http://download.redis.io/releases/redis-5.0.0.tar.gz 2.解压 tar xzvf redis-5.0.0. ...

  10. js_页面关闭beforeunload事件

    做圆桌爆文公众号的时候,需要对阅读的文章进行时间统计.是这个公众号的核心功能,客户把文章转发到朋友圈或者转给朋友,记录谁阅读此文章和阅读时长进行记录,从而展示给客户. 功能点是,关闭页面时触发事件,请 ...