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 ...
随机推荐
- CXF生成client注意事项
1. 在使用wsdl2java命令生成client文件时在Service的Java文件中面出现super构造错误,这是因为jax-ws2.2规约与java6冲突 故须要减少jax-ws规约版本号. ...
- 在Ubuntu安装go编译环境
在Ubuntu安装go编译环境 好记性不如烂笔头,所以趁热打铁记录下golang编译环境的安装过程. 首先下载一些依赖包: sudo apt-get install bison ed gawk gcc ...
- mysql复制表结构和内容
许多时候我们想复制一张表部分或者全部内容,或者只复制一张表的框架,这种需求应该说我们很常见. 其实想要实现这种需求十分简单. 表一: mysql> select * from student_i ...
- selenium之坑(StaleElementReferenceException: Message: Element not found in the cache...)
有时候循环点击一列链接,只能点到第一个,第二个就失败了 原因是第二个已经是新页面,当然找不到之前页面的元素.就算是后退回来的,页面也是不一样的 页面长的一样不一定是同一张页面,就像两个人长的一样不一定 ...
- Hive与Hbase关系整合
近期工作用到了Hive与Hbase的关系整合,虽然从网上参考了很多的资料,但是大多数讲的都不是很细,于是决定将这块知识点好好总结一下供大家分享,共同掌握! 本篇文章在具体介绍Hive与Hbase整合之 ...
- jQuery图片水平滑动延迟加载动画
在线演示 本地下载
- shell单例-处理方案
shell单例:当某一个shell脚本需要重复执行时(shell定时任务 etc),为了避免多个相同任务之间交叉,造成数据的混乱或者错误,需要脚本单例执行. 就是前一个进程执行时,后一个进程需要阻塞等 ...
- EntityFramework 学习 一 Add Entity Graph using DbContext:
//Create student in disconnected mode Student newStudent = new Student() { StudentName = "New S ...
- ZOJ 2724 Windows Message Queue (二叉堆,优先队列)
思路:用优先队列 priority_queue,简单 两种方式改变队列 的优先级 (默认的是从大到小) #include<iostream> #include<queue> # ...
- Mybatis中collection与association的区别
association是多对一的关系 collection是一个一对多的关系