题目描述
题解
单调栈裸题。
改了一个姿势,原来是一遍单调栈维护两个值,改成了两遍单调栈算出l和r。
我感觉第二种更好理解吧
两个代码都贴出来。
代码
#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
#define N 50005
int n,h[N],val[N],Max,stack[N],top,sum[N],ans;
struct hp{int l,r;}f[N];
void push(int x){
while (h[stack[top]]<h[x]&&top)
{
f[x].l=f[stack[top]].l;
f[stack[top-1]].r=f[stack[top]].r;
--top;
}
if (h[x]==h[stack[top]]) f[x].l=f[stack[top]].l;
f[stack[top]].r=f[x].r;
stack[++top]=x;
}
int main(){
scanf("%d",&n);
for (int i=1;i<=n;++i) scanf("%d%d",&h[i],&val[i]),f[i].l=f[i].r=i;
for (int i=1;i<=n;++i) push(i);
while (top)
{
f[stack[top-1]].r=f[stack[top]].r;
--top;
}
for (int i=1;i<=n;++i) sum[f[i].l-1]+=val[i],sum[f[i].r+1]+=val[i];
for (int i=1;i<=n;++i) ans=max(ans,sum[i]);
printf("%d\n",ans);
}
#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
#define N 50005
int n,h[N],val[N],l[N],r[N],Max,stack[N],top,sum[N],ans;
int main(){
scanf("%d",&n);
for (int i=1;i<=n;++i) scanf("%d%d",&h[i],&val[i]),l[i]=1,r[i]=n;
top=0;
for (int i=1;i<=n;++i)
{
while (top&&h[stack[top]]<h[i])
{
r[stack[top]]=i-1;
--top;
}
stack[++top]=i;
}
top=0;
for (int i=n;i>=1;--i)
{
while (top&&h[stack[top]]<h[i])
{
l[stack[top]]=i+1;
--top;
}
stack[++top]=i;
}
for (int i=1;i<=n;++i) sum[l[i]-1]+=val[i],sum[r[i]+1]+=val[i];
for (int i=1;i<=n;++i) ans=max(ans,sum[i]);
printf("%d\n",ans);
}
总结
单调栈再好好想想。
本文介绍了一种使用单调栈解决区间最大值问题的方法。通过两种不同的实现方式,详细展示了如何利用单调栈来高效地计算特定条件下的最大值。第一种方法在一个遍历中维护两个值,而第二种方法则分为两次遍历来分别计算左界和右界。
&spm=1001.2101.3001.5002&articleId=51302017&d=1&t=3&u=e1d3a08032af40b69d8a25a70a99899f)
999

被折叠的 条评论
为什么被折叠?



