hdu 1506(好题+DP或者RMQ)
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
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 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.
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.
4 1000 1000 1000 1000
0
4000
#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)的更多相关文章
- HDU 1506 Largest Rectangle in a Histogram (dp左右处理边界的矩形问题)
E - Largest Rectangle in a Histogram Time Limit:1000MS Memory Limit:32768KB 64bit IO Format: ...
- HDU 4778 状压DP
一看就是状压,由于是类似博弈的游戏.游戏里的两人都是绝对聪明,那么先手的选择是能够确定最终局面的. 实际上是枚举最终局面情况,0代表是被Bob拿走的,1为Alice拿走的,当时Alice拿走且满足变换 ...
- HDOJ(HDU).2602 Bone Collector (DP 01背包)
HDOJ(HDU).2602 Bone Collector (DP 01背包) 题意分析 01背包的裸题 #include <iostream> #include <cstdio&g ...
- Bomb HDU - 3555 (数位DP)
Bomb HDU - 3555 (数位DP) The counter-terrorists found a time bomb in the dust. But this time the terro ...
- hdu 1505 && hdu1506 &&hdu 2830 && 2870 总结---------DP之状图选最大矩形
/* 多谢了“闭眼,睁眼” 同学给我一套dp专题,不然真是没接触过这种题型. 做个4个简单的,很高兴有所收获. 2013-08-06 /* HDU 1506 最基础的一道题目,其主要精髓就在于两个数组 ...
- HDU 1506 Largest Rectangle in a Histogram set+二分
Largest Rectangle in a Histogram Problem Description: A histogram is a polygon composed of a sequenc ...
- HDU 1011 树形背包(DP) Starship Troopers
题目链接: HDU 1011 树形背包(DP) Starship Troopers 题意: 地图中有一些房间, 每个房间有一定的bugs和得到brains的可能性值, 一个人带领m支军队从入口(房 ...
- HDU 1950 Bridging signals (DP)
职务地址:HDU 1950 这题是求最长上升序列,可是普通的最长上升序列求法时间复杂度是O(n*n).显然会超时.于是便学了一种O(n*logn)的方法.也非常好理解. 感觉还用到了一点贪心的思想. ...
- hdu 2296 aC自动机+dp(得到价值最大的字符串)
Ring Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submis ...
随机推荐
- AtCoder Regular Contest 081 E - Don't Be a Subsequence(字符串DP)
引用自:onion_cyc 字符串DP一直不是强项...以后没思路的题就想DP和网络流23333333 f[i]表示从i开始的后缀非子序列的最短长度 pos[i][j]表示从i开始的j字符最早出现位 ...
- [学习笔记]FFT——快速傅里叶变换
大力推荐博客: 傅里叶变换(FFT)学习笔记 一.多项式乘法: 我们要明白的是: FFT利用分治,处理多项式乘法,达到O(nlogn)的复杂度.(虽然常数大) FFT=DFT+IDFT DFT: 本质 ...
- 20181015 考试记录&数论
题目传送门 W神爷的题解 数论 小 M 的算式 [问题描述] 小 M 在做数学作业的时候遇到了一个有趣的问题:有一个长度为 n 的数字 串 S,小 M 需要在数字之间填入若干个“+”和恰好一个“=”, ...
- ACM1004 Let the balloons fly
These code is for the problem "Let the balloons Fly" in ACM 1004 which need deal with stri ...
- last-child 选择器
<!DOCTYPE html> <html> <head> <style> p:last-child //p的父类 的子类下最后一个,就是p兄弟层的最后 ...
- DIV CSS display(block,inline,none)的属性教程
display:inline.block.inline-block的区别 display:block就是将元素显示为块级元素. block元素的特点是: 总是在新行上开始: 高度,行高以及顶和底边距都 ...
- String StrigBuffer StringBuilder 浅解
1.String是最基本的字符串类,用于表示字符串. 特点:对象内容不可变,但可以通过指向不同的对象来“表示”不同的内容. 使用场景:如果不涉及到内容改变,可以使用String. 注意:如果想将Str ...
- Lua中调用C++方法
目前项目,使用了Lua脚本,至于使用Lua的好处不再赘述了.于是对Tolua做了一些小小的学习,总结一下吧. 主要说一下如何在Lua中调用C++方法. Lua调用C++的桥梁,是tolua.tolua ...
- 关于this问题
对于关键字this,其实很好理解,谁调用我就指向谁.下面举个例子说明: 其实这也是在学习闭包中的一个案例: var name = "The window"; var obj = { ...
- 【shell】shell编程(六)-shell函数的应用
linux shell 可以用户定义函数,然后在shell脚本中可以随便调用. shell中函数的定义格式如下: [ function ] funname [()] { action; [return ...