单调性优化:单调栈与单调队列

单调性优化:单调栈与单调队列

一、单调栈

单调栈,就是要维护一个栈,单调递增或递减。一般地,放入元素时,如果栈顶的元素不符合单调递增(或递减),那就把它弹出,再查栈顶。直到符合或栈空了,再把元素放入。

适用于快速求每个数两侧比它大(或小)的数的位置。

例题-柱状图中最大的矩形

算法

·其实很简单
·在这种方法中,我们维护一个栈。
·一开始,我们把 -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比你小又比你强,那你就废了没用了

解决的问题:

f(x)=opti=bound[x]x1(const[i])

对于这样一类动态规划问题,我们可以运用单调队列来解决:
其中bound[x]随着x单调不降,const[i]则是可以根据i在常数时间内确定的唯一的常数。这类问题,一般用单调队列在很优美的时间内解决。

例题-【模板】单调队列

·队列中的元素其对应在原来的列表中的顺序必须是单调递增的。
·队列中元素的大小必须是单调递增(减/甚至是自定义也可以)

练习-好消息,坏消息

·破环成链+单调队列

练习-课后期末考试滑溜滑溜补习班

·简单的推柿子+单调队列

posted @   Little09  阅读(83)  评论(0编辑  收藏  举报
编辑推荐:
· .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语句:使用策略模式优化代码结构
点击右上角即可分享
微信分享提示