hdu1506单调栈的宽度
很好的题目,单调栈上的宽度如何求
题解:https://blog.csdn.net/baidu_35643793/article/details/64440095
单调队列和单调栈都是去除没有用的数据,对于本题来说,当一个高度小于前面高度时,那么前面的高度就没用了,因为此时后面柱体宽度拓展的限制条件就是当前高度较小的柱体,而当前柱体只要将之前柱体的宽度吸收进来即可
从左到右遍历每个元素,元素可以向左边扩展到第一个比其低的数,也可以向右扩展到第一个比其低的数,现在让元素入单调栈,栈顶元素大于栈底元素。元素的左宽度在其入栈时求出,是最后一个出栈元素的宽度+1
每个元素在入栈弹出栈内元素的过程中,都可以求出出栈元素的右宽度,是其前面出站元素的左宽度的总和
/* 单调栈:每个元素在入栈时可以的到其左侧可以拓展的宽度,在出站时可以得到其右侧可以拓展的宽度 用两个栈记录下标和左侧宽度 */ #include<bits/stdc++.h> using namespace std; #define maxn 100005 #define ll long long int q[maxn],w[maxn],h,n; int main(){ while(scanf("%d",&n),n){ memset(q,-1,sizeof q); int top=0; ll ans=0; for(int i=1;i<=n+1;i++){ if(i!=n+1) scanf("%d",&h); else h=0; if(h>q[top]) q[++top]=h,w[top]=1; else { ll cnt=0; while(h<=q[top]){ ans=max(ans,(w[top]+cnt)*q[top]); cnt=cnt+w[top--];//出栈元素的左宽不断累加就是栈顶元素的右宽 } q[++top]=h; w[top]=cnt+1;//新入栈的元素左宽是最后一个出队元素总宽+1 } } printf("%lld\n",ans); } return 0; }