hdu 1506 单调栈问题
题目链接: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 单调栈问题的更多相关文章
- hdu 1506 单调栈
#include <bits/stdc++.h> #define PI acos(-1.0) #define mem(a,b) memset((a),b,sizeof(a)) #defin ...
- hdu 5033 单调栈 ****
看出来是单调栈维护斜率,但是不会写,2333,原来是和询问放在一起的 #include <iostream> #include <cstdio> #include <cs ...
- hdu 5875(单调栈)
Function Time Limit: 7000/3500 MS (Java/Others) Memory Limit: 262144/262144 K (Java/Others)Total ...
- HDU 5033 (单调栈维护凸包) Building
题意: 一个人在x轴上,他的左右两侧都有高楼,给出楼的横坐标Xi和高度Hi还有人的位置pos,求人所能看到的天空的最大角度. 分析: 将建筑物和人的位置从左到右排序,对于每个位置利用栈求一次人左边建筑 ...
- hdu 4923 单调栈
http://acm.hdu.edu.cn/showproblem.php?pid=4923 给定一个序列a,元素由0,1组成,求一个序列b,元素在0~1之间,并且保证递增.输出最小的∑(ai−bi) ...
- hdu 3410 单调栈
http://acm.hdu.edu.cn/showproblem.php?pid=3410 Passing the Message Time Limit: 2000/1000 MS (Java/Ot ...
- hdu 1505 单调栈升级版
#include <bits/stdc++.h> #define PI acos(-1.0) #define mem(a,b) memset((a),b,sizeof(a)) #defin ...
- HDU -1506 Largest Rectangle in a Histogram&&51nod 1158 全是1的最大子矩阵 (单调栈)
单调栈和队列讲解:传送门 HDU -1506题意: 就是给你一些矩形的高度,让你统计由这些矩形构成的那个矩形面积最大 如上图所示,如果题目给出的全部是递增的,那么就可以用贪心来解决 从左向右依次让每一 ...
- hdu 1506 Largest Rectangle in a Histogram(单调栈)
L ...
随机推荐
- 5.Django数据库配置
Django默认支持sqlite.mysql.oracle.postgresql数据库,像db2和sqlserver需要安装第三方的支持 配置Django数据库:\hello_django\hello ...
- go语言之接口二
接口查询: 先来看如下的结构.结构体File实现了Read,Writer,Seek,Close的方法 type File struct{ } func (f *File) Read(buf []byt ...
- mysql索引学习----2----创建索引、修改索引、删除索引的命令语句
查看表中已经存在 index:show index from table_name; 创建和删除索引索引的创建可以在CREATE TABLE语句中进行,也可以单独用CREATE INDEX或ALTER ...
- Data Structure Binary Tree: Convert an arbitrary Binary Tree to a tree that holds Children Sum Property
http://www.geeksforgeeks.org/convert-an-arbitrary-binary-tree-to-a-tree-that-holds-children-sum-prop ...
- [原创]java WEB学习笔记05:Servlet中的ServletConfig对象
本博客为原创:综合 尚硅谷(http://www.atguigu.com)的系统教程(深表感谢)和 网络上的现有资源(博客,文档,图书等),资源的出处我会标明 本博客的目的:①总结自己的学习过程,相当 ...
- python 3 mysql sql逻辑查询语句执行顺序
python 3 mysql sql逻辑查询语句执行顺序 一 .SELECT语句关键字的定义顺序 SELECT DISTINCT <select_list> FROM <left_t ...
- Vim 命令记录与回放
步骤如下: q+(a..z)寄存器名: 执行你要执行的操作: q 结束操作: 调用为@+寄存器: 列子如下: 在写PHP 程序时用的比较多的是创建函数: 如 function add_in(){ } ...
- BioNLP概述
BioNLP概述 工具: GENIA Tagger:GENIA Tagger是一个主要应用于生物医学文本领域的词性标注和浅层语法分析工具,GENIA Tagger在GENIA语料上的词性标记性能F-s ...
- phalcon:官方多模块支models层,mode数据库配置(二)
phalcon:官方多模块支models层,mode数据库配置(二) 利用:\pahlcon\mvc\model\Manager::registerNamespaceAlias()方法获取多模块下的m ...
- Python习题-一个函数实现读写功能
def new_op_file(filename,content=None): f = open(filename,'a+') f.seek(0) if content: #非空即真,如果有内容就往下 ...