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. selenium - webdriver - ActionChains类(鼠标操作)

    ActionChains 类提供了鼠标操作的常用方法: perform(): 执行所有 ActionChains 中存储的行为: context_click(): 右击: double_click() ...

  2. java 在centos6.5+eclipse环境下调用opencv实现sift算法

    java 在centos6.5+eclipse环境下调用opencv实现sift算法,代码如下: import org.opencv.core.Core; import org.opencv.core ...

  3. Xcode 问题

    问题: 昨天在写代码的时候,不知道修改了哪个地方,Xcode6突然犯病了,在当前项目下无法代码提示,但是在新建工程中没有任何问题,其中重装了Xcode6也没有把问题解决, 最终的解决办法是: 在fin ...

  4. springboot的application.properties与.yml的区别

    现在我们的application.properties文件内容是: server.port=8090 server.session-timeout=30 server.context-path= se ...

  5. 使用Android Studio调试UiAutomator过程中遇到的问题

    声明: 这里纪录了个人学习和使用Android Studio调试UiAutomator过程中遇到遇到的问题,不定时进行更新,欢迎一起交流学习 1.Excution faild for task ‘:a ...

  6. ZooKeeper翻译(一)

    欢迎来到Apache ZooKeeper的世界 Apache Zookeeper是一个为了开发和维护一个开源的服务的一个尝试,这个服务使高可用的分布式协作成为可能. ZooKeeper是什么? Zoo ...

  7. spring和Quartz的集群(二)

    一:前沿 写完了这两篇才突然想起来,忘记了最关键的东西,那就是在配置文件这里的配置,还有数据库的配置.这是郁闷啊!继续吧! 二:内容配置 我们在集成的时候需要自己配置一个quartz.properti ...

  8. LightOJ 1278 - Sum of Consecutive Integers 分解奇因子 + 思维

    http://www.lightoj.com/volume_showproblem.php?problem=1278 题意:问一个数n能表示成几种连续整数相加的形式 如6=1+2+3,1种. 思路:先 ...

  9. LightOJ 1269 - Consecutive Sum Trie树

    题意:给出一串序列,求区间连续异或值的最大和最小. 思路:如果不是出在专题里,想不到可以用字典树做.先求前缀异或值,转为二进制,加入Trie树中,如果要求最大,就是尽可能走和当前位数字相反的,这样异或 ...

  10. iOS-Apple苹果iPhone开发公开API

      iOS-Apple苹果iPhone开发 //技术博客http://www.cnblogs.com/ChenYilong/   新浪微博http://weibo.com/luohanchenyilo ...