hdu1506单调栈的宽度

时间:2024-08-19 23:06:50

很好的题目,单调栈上的宽度如何求

题解:https://blog.****.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,-,sizeof q);
int top=;
ll ans=;
for(int i=;i<=n+;i++){
if(i!=n+) scanf("%d",&h);
else h=;
if(h>q[top]) q[++top]=h,w[top]=;
else {
ll cnt=;
while(h<=q[top]){
ans=max(ans,(w[top]+cnt)*q[top]);
cnt=cnt+w[top--];//出栈元素的左宽不断累加就是栈顶元素的右宽
}
q[++top]=h;
w[top]=cnt+;//新入栈的元素左宽是最后一个出队元素总宽+1
}
}
printf("%lld\n",ans);
}
return ;
}