当前位置: 首页 > news >正文

第三章:单调栈

1.单调栈的模版

 4种情况 

 

代码实现: 

//1.找数字左侧比它大并且是最近的数的下标
//单调栈:单调递减,如果比它小,不要,比它大,推入队列
#include<iostream>
#include<stack>
#include<vector>
using namespace std;

const int N = 1e3 + 10;
int n;
int a[N];
int ret[N];
//1.找左侧最近的且比它大的数字
void fun1()
{
	stack<int> s;
	for (int i = 1; i <= n; i++)
	{
		int t = a[i];
		while (s.size() && a[s.top()] <= t)s.pop();

		if (s.size())ret[i] = s.top();
		s.push(i);
	}
	for (int i = 1; i <= n; i++)
	{
		cout << ret[i] << " ";
	}
}
//2.找左侧最近且比它小的数字
void fun2()
{
	stack<int> s;
	for (int i = 1; i <= n; i++)
	{
		int t = a[i];
		while (s.size() && a[s.top()] >= t)s.pop();

		if (s.size())ret[i] = s.top();
		s.push(i);
	}
	for (int i = 1; i <= n; i++)
	{
		cout << ret[i] << " ";
	}
}
//3.找右侧最近且比它大的元素,1的逆序
void fun3()
{
	stack<int> s;
	for (int i = n; i >= 1; i--)
	{
		int t = a[i];
		while (s.size() && a[s.top()] >= t)s.pop();

		if (s.size())ret[i] = s.top();
		s.push(i);
	}
	for (int i = 1; i <= n; i++)
	{
		cout << ret[i] << " ";
	}
}
//4.找右侧最近且比它小的元素,2的逆序
void fun2()
{
	stack<int> s;
	for (int i = n; i >= 1; i--)
	{
		int t = a[i];
		while (s.size() && a[s.top()] >= t)s.pop();

		if (s.size())ret[i] = s.top();
		s.push(i);
	}
	for (int i = 1; i <= n; i++)
	{
		cout << ret[i] << " ";
	}
}
int main()
{
	cin >> n;
	for (int i = 1; i <= n; i++)cin >> a[i];
	fun2();

}

注意:

栈里面存的是元素的下标。

总结和巧记 :

1.记录详情 - 洛谷 | 计算机科学教育新生态

 

#include<iostream>
#include<stack>
using namespace std;

int n;
const int N = 3e6+10;
int a[N];
int ret[N];

int main()
{
    cin>>n;
    for(int i = 1;i <= n;i++)cin>>a[i];

    stack<int> s;
    for(int i = n;i >= 1;i--)
        {
            int t = a[i];
            while(s.size()&&a[s.top()]<=t)s.pop();

            if(s.size())ret[i] = s.top();
            s.push(i);
        }
    for(int i = 1;i <= n;i++)cout<<ret[i]<<" ";
}

2.P1901 发射站 - 洛谷

 

#include<iostream>
#include<stack>
using namespace std;

const int N = 1e6 + 10;
int h[N], v[N];
int ret[N];

int main()
{
	int n; cin >> n;
	for (int i = 1; i <= n; i++)
	{
		cin >> h[i] >> v[i];
	}
	stack<int> s;
	//找左边最近且比它大的元素
	for (int i = 1; i <= n; i++)
	{
		int t = h[i];//当前元素
		while (s.size() && h[s.top()] <= t)//在栈中找到一个比它大的元素
		{
			s.pop();
		}
		if (s.size())ret[s.top()] += v[i];//比它大的元素加上它的power
		s.push(i);//把该元素推进栈中
	}
	//清空栈
	while (s.size())s.pop();
	//找右边最近且比它大的元素
	for (int i = n; i >=1; i--)
	{
		int t = h[i];
		while (s.size() && h[s.top()] <= t)
		{
			s.pop();
		}
		if (s.size())ret[s.top()] += v[i];//比它大的元素加上它的power
		s.push(i);
	}
	int res = 0;
	for (int i = 1; i <= n; i++)
	{
		res = max(res, ret[i]);
	}
	cout << res << endl;
}

前后使用单调栈,找出左右离他最近并且比它的元素,把它的power加到该元素下,再把下标推入栈中

3.SP1805 HISTOGRA - Largest Rectangle in a Histogram - 洛谷

 

#include<iostream>
#include<stack>
using namespace std;

typedef long long LL;
const int N = 1e5 + 10;
LL a[N];
LL l[N];//记录每个元素左侧比它小的元素的下标
LL r[N];//记录每个元素右侧比它小的元素的下标
int n;

int main()
{
	while (cin >> n, n)
	{
		for (int i = 1; i <= n; i++)cin >> a[i];
		stack<int> s;
		//找每个元素左边比它小的元素的下标
		for (int i = 1; i <= n; i++)
		{
			int t = a[i];
			while (s.size() && a[s.top()] >= t)
			{
				s.pop();
			}
			if (s.size())l[i] = s.top();
			else l[i] = 0;//找不到的话,栈就变成空了,就把左侧设置成0
			s.push(i);
		}
		//清空栈
		while (s.size())s.pop();
		//找每个元素右侧比它小的元素的下标
		for (int i = n; i >= 1; i--)
		{
			int t = a[i];
			while (s.size() && a[s.top()] >= t)s.pop();
			if (s.size())r[i] = s.top();
			else r[i] = n + 1;//找不到的话,栈就变成空了,就把左侧设置成n+1
			s.push(i);
		}
		LL ret = 0;
		for (int i = 1; i <= n; i++)
		{
			ret = max(ret, a[i] * (r[i] - l[i] - 1));
		}
		cout << ret << endl;
	}
}

 找到每个元素左右侧的最近的较小值的下标,->长

自己的高->高

遍历,面积找最大值

注意:

当超过边界的时候,栈就为空,左侧设置成0 ,右侧设置成n+1

相关文章:

  • MATLAB神经网络优化1000个案例算法汇总
  • KV Cache 在自回归生成中的作用及显存优化
  • Python连接数据库进行增删改查
  • Postman高级功能深度解析:Mock Server与自动化监控——构建高效API测试与监控体系
  • DeepSeek+知网研学赋能研究生学习课程:降低科研压力与提升科研效率
  • 在Orin上查看CUDA cuDNN TensorRT的版本
  • Nat Commun | 单细胞和空间转录组学分析构建NSCLC免疫和非免疫区图谱
  • 示波器直流耦合和交流耦合的区别
  • MySQL为什么默认使用RR隔离级别?
  • 24. 状态模式
  • 栈/堆/static/虚表
  • Pytest基础使用
  • 【产品小白】如何运营一个成熟的产品
  • 《深度剖析:BERT与GPT——自然语言处理架构的璀璨双星》
  • SeaTunnel简易封装方案:让数据集成更简单
  • 「低延迟+快速集成:Amazon IVS如何重塑实时互动视频体验?」
  • python中的min函数的key的用法 - abs绝对值
  • 误杀!微软道歉了!
  • 【CVPR2024-工业异常检测】PromptAD方法(CLIP和提示学习)
  • HTML5响应式使用css媒体查询
  • 80后女博士黄双燕拟提名为内蒙古盟市政府(行署)副职人选
  • 机器人为啥热衷“搞体育”,经济日报:是向加速融入日常生活发起的冲锋
  • 证监会强化上市公司募资监管七要点:超募资金不得补流、还贷
  • 商务部:长和集团出售港口交易各方不得规避审查
  • 新任国防部新闻发言人蒋斌正式亮相
  • 视频丨中国海警成功救助8名外籍遇险渔民,韩方向中方致谢