题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1506

题目的意思其实就是要找到一个尽可能大的矩形来完全覆盖这个矩形下的所有柱子,只能覆盖柱子,不能留空。

我们求得的面积其实就是Max{s=(right[i] - left[i] + 1)*height[i];(i>=1&&i<=n)}

每一个柱子都要尽可能向左向右延伸,使得获得最大的面积。

此时我就要用到单调栈

单调栈就是栈内元素单调递增或者单调递减的栈,单调栈只能在栈顶操作。

http://blog.csdn.net/liujian20150808/article/details/50752861

这里我们还是做一个总结

单调栈的维护是 O(n) 级的时间复杂度,因为所有元素只会进入栈一次,并且出栈后再也不会进栈了。

单调栈的性质:

1.单调栈里的元素具有单调性

2.元素加入栈前,会在栈顶端把破坏栈单调性的元素都删除

3.使用单调栈可以找到元素向左遍历第一个比他小的元素,也可以找到元素向左遍历第一个比他大的元素。

基于此题,我们可以知道,先每一次从左到右放入柱子(保持递增单调栈),也就说一旦有一个柱子和栈顶元素一比发现比它大,那么这个柱子首先要记录它的left值为自己的本身的下标,如果发现这个柱子比栈顶的小,我们依次将栈顶元素出栈,直至又能组成递增的序列,此时这个柱子的left值就为现在栈顶的left值。

后面我们从右向左放入柱子(保持的依旧是递增的单调栈)。获得right值。

代码如下

 #include<iostream>
#include<cstdio>
#include<cstring>
#include<stack>
#define LL long long
using namespace std;
const int MAXN = ;
struct node
{
LL height;
int left;
int right;
int index;
};
node nd[MAXN];
int n;
stack <node> st;//定义一个单调栈
void clr()
{
while(!st.empty())
st.pop();
}
LL work()
{
clr();
for(int i = ;i<=n;i++)
{
if(st.empty())
{
nd[i].left = i;
st.push(nd[i]);
}
else
{
node td = st.top();
if(td.height<nd[i].height)
{
nd[i].left = i;
st.push(nd[i]);
}
else
{
bool flag=false;
int c;
while(!st.empty())
{
if((st.top()).height>=nd[i].height)
{
c = (st.top()).left;
st.pop();
}
else
{
nd[i].left = c;
flag =true;
st.push(nd[i]);
break;
}
}
if(flag == false)
{
nd[i].left = c;
st.push(nd[i]);
}
}
}
}
clr();
for(int i = n;i>=;i--)
{
if(st.empty())
{
nd[i].right = i;
st.push(nd[i]);
}
else
{
node td = st.top();
if(td.height<nd[i].height)
{
nd[i].right = i;
st.push(nd[i]);
}
else
{
bool flag=false;
int c;
while(!st.empty())
{
if((st.top()).height>=nd[i].height)
{
c = (st.top()).right;
st.pop();
}
else
{
nd[i].right = c;
st.push(nd[i]);
flag = true;
break;
}
}
if(flag == false)
{
nd[i].right = c;
st.push(nd[i]);
}
}
}
}
LL maxs = ;
LL s;
for(int i = ;i<=n;i++)
{
s = (nd[i].right - nd[i].left + )*nd[i].height;
if(maxs<s)
maxs = s;
}
return maxs;
}
int main()
{
while(~scanf("%d",&n))
{
if(n==)
break;
for(int i = ;i<=n;i++)
{
nd[i].index = i;
scanf("%I64d",&nd[i].height);
}
cout<<work()<<endl;
}
return ;
}

hdu 1506 单调栈问题的更多相关文章

  1. hdu 1506 单调栈

    #include <bits/stdc++.h> #define PI acos(-1.0) #define mem(a,b) memset((a),b,sizeof(a)) #defin ...

  2. hdu 5033 单调栈 ****

    看出来是单调栈维护斜率,但是不会写,2333,原来是和询问放在一起的 #include <iostream> #include <cstdio> #include <cs ...

  3. hdu 5875(单调栈)

    Function Time Limit: 7000/3500 MS (Java/Others)    Memory Limit: 262144/262144 K (Java/Others)Total ...

  4. HDU 5033 (单调栈维护凸包) Building

    题意: 一个人在x轴上,他的左右两侧都有高楼,给出楼的横坐标Xi和高度Hi还有人的位置pos,求人所能看到的天空的最大角度. 分析: 将建筑物和人的位置从左到右排序,对于每个位置利用栈求一次人左边建筑 ...

  5. hdu 4923 单调栈

    http://acm.hdu.edu.cn/showproblem.php?pid=4923 给定一个序列a,元素由0,1组成,求一个序列b,元素在0~1之间,并且保证递增.输出最小的∑(ai−bi) ...

  6. hdu 3410 单调栈

    http://acm.hdu.edu.cn/showproblem.php?pid=3410 Passing the Message Time Limit: 2000/1000 MS (Java/Ot ...

  7. hdu 1505 单调栈升级版

    #include <bits/stdc++.h> #define PI acos(-1.0) #define mem(a,b) memset((a),b,sizeof(a)) #defin ...

  8. HDU -1506 Largest Rectangle in a Histogram&&51nod 1158 全是1的最大子矩阵 (单调栈)

    单调栈和队列讲解:传送门 HDU -1506题意: 就是给你一些矩形的高度,让你统计由这些矩形构成的那个矩形面积最大 如上图所示,如果题目给出的全部是递增的,那么就可以用贪心来解决 从左向右依次让每一 ...

  9. hdu 1506 Largest Rectangle in a Histogram(单调栈)

                                                                                                       L ...

随机推荐

  1. jquery点击一组按钮中的一个,跳转至对应页面处理策略。(如点击订单列表中的一个订单,跳转至该订单的详情)

    将改组按钮的数据设置一个相同的属性(如class),然后每个按钮设置不同的id 当用户点击属性为class的按钮,根据id属性来判断点击的是哪个按钮,然后进行相关操作. 代码示例: <scrip ...

  2. python基础-第五篇-5.1冒泡排序

    几个月过去了,小白逐渐对公司的后端服务熟悉了,不过这天小白又接到一封神秘邮件,是景女神发来的:公司急需一批对语言算法有些了解的优秀员工,鉴于你在公司的表现很不错,现在给到你一个培训机会,请速到开发部报 ...

  3. go语言之面向对象一

    在Go语言中, 你可以给任意类型(包括内置类型,但不包括指针类型)添加相应的办法.示例如下: type Integer int func (a Integer) Less(b Integer) boo ...

  4. Tensorflow官方文档中文版——第二章(瞎奖杯写)

    包含如下几个部分: 1.面向机器学习初学者的 MNIST 初级教程 2.面向机器学习专家的 MNIST 高级教程 3.TensorFlow 使用指南 4.卷积神经网络 5.单词的向量表示(word e ...

  5. spring项目改名后不能启动的原因及解决办法

    今日修改了一个spring项目的项目名称,修改后启动项目Debug as->Debug on server,过了很久也没有出现web首页,仔细看项目的定时器已经启动,eclipse的Consol ...

  6. mysql主从复制(windows下)

    简单搭建mysql主从服务器(双向复制),仅供学习之用. 1.下载mysql-advanced-5.6.16-winx64.zip 下载完成后解压,重命名成mysql,分别放入两台服务器(看第二点集群 ...

  7. link_to嵌套

    = link_to theses_path, :class=>"btn" do .text-center 购买

  8. vim 真是上瘾啊

    再次更新 .vimrc " leaderlet mapleader = ","nnoremap <leader>ev :vsplit ~/.vimrc< ...

  9. while 读取文件内容

    exec < filename while read line;do echo $line done 方法1 while read line;do echo $line done<$ 方法 ...

  10. 剑指offer之 二维数组的查找

    package Problem3; public class Find { /* * 题目描述:二维数组中的查找 * 在一个二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下的顺序排 ...