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值。
代码如下
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<stack> 5 #define LL long long 6 using namespace std; 7 const int MAXN = 100005; 8 struct node 9 { 10 LL height; 11 int left; 12 int right; 13 int index; 14 }; 15 node nd[MAXN]; 16 int n; 17 stack <node> st;//定义一个单调栈 18 void clr() 19 { 20 while(!st.empty()) 21 st.pop(); 22 } 23 LL work() 24 { 25 clr(); 26 for(int i = 1;i<=n;i++) 27 { 28 if(st.empty()) 29 { 30 nd[i].left = i; 31 st.push(nd[i]); 32 } 33 else 34 { 35 node td = st.top(); 36 if(td.height<nd[i].height) 37 { 38 nd[i].left = i; 39 st.push(nd[i]); 40 } 41 else 42 { 43 bool flag=false; 44 int c; 45 while(!st.empty()) 46 { 47 if((st.top()).height>=nd[i].height) 48 { 49 c = (st.top()).left; 50 st.pop(); 51 } 52 else 53 { 54 nd[i].left = c; 55 flag =true; 56 st.push(nd[i]); 57 break; 58 } 59 } 60 if(flag == false) 61 { 62 nd[i].left = c; 63 st.push(nd[i]); 64 } 65 } 66 } 67 } 68 clr(); 69 for(int i = n;i>=1;i--) 70 { 71 if(st.empty()) 72 { 73 nd[i].right = i; 74 st.push(nd[i]); 75 } 76 else 77 { 78 node td = st.top(); 79 if(td.height<nd[i].height) 80 { 81 nd[i].right = i; 82 st.push(nd[i]); 83 } 84 else 85 { 86 bool flag=false; 87 int c; 88 while(!st.empty()) 89 { 90 if((st.top()).height>=nd[i].height) 91 { 92 c = (st.top()).right; 93 st.pop(); 94 } 95 else 96 { 97 nd[i].right = c; 98 st.push(nd[i]); 99 flag = true; 100 break; 101 } 102 } 103 if(flag == false) 104 { 105 nd[i].right = c; 106 st.push(nd[i]); 107 } 108 } 109 } 110 } 111 LL maxs = 0; 112 LL s; 113 for(int i = 1;i<=n;i++) 114 { 115 s = (nd[i].right - nd[i].left + 1)*nd[i].height; 116 if(maxs<s) 117 maxs = s; 118 } 119 return maxs; 120 } 121 int main() 122 { 123 while(~scanf("%d",&n)) 124 { 125 if(n==0) 126 break; 127 for(int i = 1;i<=n;i++) 128 { 129 nd[i].index = i; 130 scanf("%I64d",&nd[i].height); 131 } 132 cout<<work()<<endl; 133 } 134 return 0; 135 }
转载于:https://www.cnblogs.com/fancy-itlife/p/5295293.html
hdu 1506 单调栈问题相关推荐
- hdu 4252(单调栈)
题意:一张相片上的很多建筑相互遮住了,根据高低不同就在相片上把一座高楼的可见部分作为一个矩形,并用数字描述其高度,若一张相片上的两个建筑群中间有空地,高度则为0;求最少有多少个建筑; 解题思路:这道题 ...
- 算法竞赛入门与进阶 (二)单调队列、单调栈
栈(stack)和队列( queue ) 1.栈的定义:栈是限定仅在表头进行插入和删除操作的线性表(先进后出) 2.队列的定义:队列是一种特殊的线性表,特殊之处在于 它只允许在表的前端(front)进 ...
- HDU 1506 解题报告 Largest Rectangle in a Histogram (单调栈)
看题传送门:http://acm.hdu.edu.cn/showproblem.php?pid=1506 题意比较明显,就是找以某一个矩形为高的最大的矩形.这个题可以用单调栈来求解,需要注意的是如果从 ...
- hdu 1506(dp || 单调栈)
题意:这题是要找最大的矩形面积. 解题思路:这题的关键是要找每个条形能够往左和往右能够到达的最大长度.我最开始的思路是单调栈去维护,只要入栈的元素比栈顶元素小,栈顶就要出栈,并且知道其最右能够到达的最 ...
- HDU 1506 Largest Rectangle in a Histogram(dp、单调栈)
你是不是飘了?骚年! Problem Description A histogram is a polygon composed of a sequence of rectangles aligned ...
- *【HDU - 1506】【POJ - 2559】Largest Rectangle in a Histogram(单调栈或动态规划)
题干: Description A histogram is a polygon composed of a sequence of rectangles aligned at a common ba ...
- Largest Rectangle in a Histogram HDU - 1506 解题思路 单调栈
原题目 Problem Description A histogram is a polygon composed of a sequence of rectangles aligned at a c ...
- HDU多校4 - 6989 Didn‘t I Say to Make My Abilities Average in the Next Life?!(单调栈)
题目链接:点击查看 题目大意:给出一个长度为 nnn 的序列,再给出 mmm 次询问,每次询问给出一个区间 [l,r][l,r][l,r],要求输出区间 [l,r][l,r][l,r] 内 " ...
- HDU 6194 后缀数组+单调栈
题意: 题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6194 找到一个字符串中恰好出现k次的子串的数目. 思路: 计算出height数组,根据heig ...
- 数据结构 单调栈+几何 摩天大楼【HDU 5033 】
HDU 5033 题目大意: 就是一个人来到充满摩天大楼的城市,所有大楼没有宽度.建一直角坐标系,给出每个建筑的高度,现在求人站在(x,0)处能够看到天空的范围.(即不被摩天大楼阻挡).答案只需要给出 ...
最新文章
- Face ID 上手体验信息汇总:面部解锁流畅,原理移植AR让人憧憬
- python条件替换_Python中Numpy条件替换操作一例
- 猎豹浏览器截图在哪 猎豹浏览器如何截图
- Aqua Data Studio数据库连接工具解决Sybase中文乱码问题
- java并发初探CyclicBarrier
- iOS-夜间模式(换肤设置)
- python3多线程第三方库_Python3标准库:concurrent.futures管理并发任务池
- Failed to execute goal org.apache.maven.plugins:maven-surefire-plugin:2.12.4
- 2017-3-01 test
- java 接受gsm信息_android 获取手机GSM/CDMA信号信息,并获得基站信息
- wps html嵌入ppt,wps文档怎么插入打开幻灯片 WPS文字添加ppt幻灯片教程
- 外卖返利系统公众号外卖cps返利小程序淘宝客程序淘客侠客外卖CPS
- 数据结构丿丶树 哈夫曼树
- 微信小程序添加体验成员,根据微信号搜索不到
- kali下使用远程桌面连接
- virtualBox上Ubuntu的网络设置(万能方法)
- c# wifi串口通信_C#中的串口通信
- Android开发——菜单(Menu)-——上下文菜单(ContextMenu)、 弹出菜单(PopupMenu)
- jdk1.7安装详细过程
- STM32输入捕获实验