单调性优化:单调栈与单调队列
单调性优化:单调栈与单调队列
一、单调栈
单调栈,就是要维护一个栈,单调递增或递减。一般地,放入元素时,如果栈顶的元素不符合单调递增(或递减),那就把它弹出,再查栈顶。直到符合或栈空了,再把元素放入。
适用于快速求每个数两侧比它大(或小)的数的位置。
算法
·其实很简单
·在这种方法中,我们维护一个栈。
·一开始,我们把 -1 放进栈的顶部来表示开始。
·按照从左到右的顺序,我们不断将柱子的序号放进栈中,保证栈的单调性。
·当元素出栈时,说明这个新元素是出栈元素向后找第一个比其小的元素
·当元素出栈后,说明新栈顶元素是出栈元素向前找第一个比其小的元素
那么这题就做完了,答案也就很好推了。
加个前缀和优化,就是单调栈的模板题了。
#include<bits/stdc++.h>
using namespace std;
long long a[1000001];
long long sum[1000001];
stack <int> t;
long long ans;
inline long long s(int x,int y)
{
return sum[y]-sum[x-1];
}
int main()
{
int n;
cin >> n;
for (int i=1;i<=n;i++)
{
cin >> a[i];
sum[i]=sum[i-1]+a[i];
}
n++;
a[n]=0;
t.push(0);
for (int i=1;i<=n;i++)
{
while (!t.empty()&&a[t.top()]>a[i])
{
long long res=a[t.top()];
t.pop();
ans=max(ans,s(t.top()+1,i-1)*res);
}
t.push(i);
}
cout << ans;
return 0;
}
二、单调队列
单调队列,就是要维护一个队列,单调递增或递减。一般地,放入元素时,先弹出末尾无效元素。如果队列首的元素不符合单调递增(或递减),那就把它弹出,再查队列首。直到符合或队列空了,再把元素放入。
如果一个oier比你小又比你强,那你就
废了没用了
解决的问题:
对于这样一类动态规划问题,我们可以运用单调队列来解决:
其中随着x单调不降,而则是可以根据i在常数时间内确定的唯一的常数。这类问题,一般用单调队列在很优美的时间内解决。
·队列中的元素其对应在原来的列表中的顺序必须是单调递增的。
·队列中元素的大小必须是单调递增(减/甚至是自定义也可以)
·破环成链+单调队列
·简单的推柿子+单调队列
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 张高兴的大模型开发实战:(一)使用 Selenium 进行网页爬虫
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构