hdu 1506(nyoj 258)Largest Rectangle in a Histogram(最大长方形(二))(单调栈)
来源:互联网 发布:5年了日本核辐射知乎 编辑:程序博客网 时间:2024/06/18 02:46
hdu题目链接:Largest Rectangle in a Histogram
nyoj题目链接:最大长方形(二)
思路一:
用三个数组记录,height[]记录高度,left[]记录当前高度延伸的最大左区间端点,right[]记录当前高度延伸的最大右区间端点。
然后通过left[]和right[]来缩短查询时间,对每一个高度形成的最大矩形面积进行比较
代码:
#include<stdio.h>#define max(a,b) (a>b?a:b)#define maxn 100000+5typedef long long LL;LL right[maxn],left[maxn],height[maxn];int main(){ LL n,cnt; while(~scanf("%lld",&n),n) { for(LL i=1; i<=n; ++i) right[i]=left[i]=i; for(LL i=1; i<=n; ++i) scanf("%lld",height+i); height[0]=-1,height[n+1]=-1; for(LL i=1; i<=n; ++i)//注意要顺序 { cnt=i-1; while(height[i]<=height[cnt]) { left[i]=left[left[cnt]];//缩短查询时间 cnt=left[i]-1; } } for(LL i=n; i>=1; --i)//注意要逆序 { cnt=i+1; while(height[i]<=height[cnt]) { right[i]=right[right[cnt]];//缩短查询时间 cnt=right[i]+1; } } LL ans=0; for(LL i=1; i<=n; ++i) ans=max(ans,(right[i]-left[i]+1)*height[i]); printf("%lld\n",ans); } return 0;}
思路二:单调栈,看了一下午才勉强搞懂(参考博客)
它就是以某一个值为最小(最大)值,然后向这个值的两侧延伸,遇到大于它(小于它)的值,就将它延伸的范围扩大,当然,一般来说,要这样做的算法复杂度为o(n^2),但是借助栈这个玩意,维护其单调增(减),就可以在o(n)的时间复杂度解决这个问题。
将一元素加入栈时,先判断它是否大于(小于)栈顶元素,若是大于(小于)栈顶元素,加入栈,(从这里开始只讲维护单调增栈)否则,将栈顶元素出栈,直到栈顶元素小于要加入栈的元素。
在此过程中,需要维护向前延伸和向后延伸的问题,对于每一个要出栈的元素,很明显它已经不能往后延伸了,所以它的最大区间范围只能是它的左区间端点到当前位置(此时计算一下它的最大面积);
而当要加入栈的元素之前有n个栈元素出栈,那么说明这n个出栈的元素都是大于或者等于要入栈的元素,此时,我们需要维护入栈元素可以向前延伸多少个元素(相当于记录它的前面有多少个元素比它大,也就是找到它的左区间端点),所以每个栈顶元素都要向出栈了的元素延伸…..
最后,将所有元素出栈,即可将所有情况考虑。这样,就在o(n)的时间复杂度内解决了上述问题………具体详见代码
代码:
#include<stdio.h>#include<string.h>#define max(a,b) (a>b?a:b)#define maxn 100000+5typedef long long LL;LL q[maxn],left[maxn];//left记录的是从这个点开始,之前有几个高度大于等于此高度int main(){ LL n,h; while(~scanf("%lld",&n),n) { for(int i=0;i<=n+1;++i) q[i]=-1,left[i]=0; LL top=0,ans=0; for(LL i=1; i<=n+1; ++i) { if(i<=n) scanf("%lld",&h); else h=0; if(h>q[top]) q[++top]=h,left[top]=1; else { LL cnt=0; while(h<=q[top])//(前n次)每次进行此操作时,不满足单调递增的元素(在它最大区间内)的结果将计算出来 {//当循环进行到第n+1次时,单调递增栈内的每一个元素都会(在它最大的区间内)进行一次计算 ans=max(ans,(cnt+left[top])*q[top]); cnt+=left[top--]; } left[++top]=cnt+1; q[top]=h; } } printf("%lld\n",ans); } return 0;}
1 0
- hdu 1506(nyoj 258)Largest Rectangle in a Histogram(最大长方形(二))(单调栈)
- HDU OJ 1506 Largest Rectangle in a Histogram 和 NYOJ 258 最大长方形(二) 【单调队列】
- HDU 1506 Largest Rectangle in a Histogram(单调栈)
- hdu 1506 Largest Rectangle in a Histogram(单调栈)
- HDU-1506 Largest Rectangle in a Histogram(单调栈)
- NYOJ-258/POJ-2559/HDU-1506 Largest Rectangle in a Histogram,最大长方形,dp或者单调队列!
- Hdu 1506 Largest Rectangle in a Histogram (DP求最大长方形面积)
- Largest Rectangle in a Histogram(最大长方形)
- HDU 1506 Largest Rectangle in a Histogram(单调队列)
- HDOJ 1506 Largest Rectangle in a Histogram(单调栈)
- hdu 1506 Largest Rectangle in a Histogram【最大长方形面积】
- HDU-1506 (POJ-2599) Largest Rectangle in a Histogram (单调栈)
- hdu 1506 Largest Rectangle in a Histogram(单调栈||dp)
- hdu - 1506 - Largest Rectangle in a Histogram(dp / 单调栈)
- POJ 2559 -- Largest Rectangle in a Histogram ( 单调栈 )
- POJ 2559 Largest Rectangle in a Histogram(单调栈)
- POJ2559 Largest Rectangle in a Histogram(单调栈)
- Largest Rectangle in a Histogram(单调栈)
- js日期操作之根据指定格式获取日期
- DOM 编程艺术 实用代码段
- 谈谈我对京东的认识(4):电商只有综合型电商,没有垂直电商
- 使用Java实现面向对象编程--集合框架
- 蓝桥杯算法提高——上帝造题五分钟(线段树+区间最小值)
- hdu 1506(nyoj 258)Largest Rectangle in a Histogram(最大长方形(二))(单调栈)
- NSSetUncaughtExceptionHandler处理异常
- Tomcat 报错:Failed to start Compenent
- Linux下高并发socket最大连接数所受的各种限制
- platform驱动学习一之led实例
- Android之TextView动态设置图片
- 详细构建工具配置文件、构建工具gulp、包管理工具bower的使用。
- POJ3169差分约束
- 51nod1268和为K的组合(枚举)