算法学习 单调栈 最大子矩阵问题

单调栈即栈的元素存储满足单调性。
单调性是基于从栈顶到栈底元素大小关系而言的,如:(代码中的大小关系可以自定义,如将<改为<=等)
单调递增栈:栈顶到栈底单调递增

	stack<int> stk;
	int tmp;
	...
	...
	while(!stk.empty()&& stk.top() < tmp) {
		stk.pop();
	}

单调递减栈:栈顶到栈底单调递减

    stack<int> stk;
	int tmp;
	...
	...
	while(!stk.empty()&& stk.top() > tmp) {
		stk.pop();
	}

单调栈特点:适用于子结构有局部单调性的数据结构,如8 9 2 1 4 5 2 3,其子结构8 9、2、1 4 5、2 3都具有局部单调递增性。

经典题目:最大子矩阵

牛客网:小A的柱状图

题目描述
柱状图是有一些宽度相等的矩形下端对齐以后横向排列的图形,但是小A的柱状图却不是一个规范的柱状图,它的每个矩形下端的宽度可以是不相同的一些整数,分别为a[i]a[i],每个矩形的高度是h[i]h[i],现在小A只想知道,在这个图形里面包含的最大矩形面积是多少。
在这里插入图片描述
输入描述:

一行一个整数N,表示长方形的个数
接下来一行N个整数表示每个长方形的宽度
接下来一行N个整数表示每个长方形的高度

输出描述:
一行一个整数,表示最大的矩形面积

说明
样例如图所示,包含的最大矩形面积是8

备注:
1≤n≤1e6,1≤a[i]≤100,1≤h[i]≤1e9

由于笔者时间有限,直接粘代码了,可以结合代码来思考
附代码:

#include <bits/stdc++.h>
#define MAXN 1000005
#define LL long long
using namespace std;

int n;
LL maxmum = -1;
LL a[MAXN], h[MAXN];
stack<int> stk;

int main() {
	scanf("%d",&n);
	for(int i = 1; i <= n; i++)
		scanf("%lld",a+i);
	for(int i = 1; i <= n; i++)
		scanf("%lld",h+i);
	stk.push(0);
	for(int i = 1; i <= n+1;i++){
		int j = stk.top();
		if(h[i] > h[j])//如果比栈顶元素的h大,入栈
			stk.push(i); 
		else {//否则,在出栈的同时维护最大值(通过枚举栈顶元素的h所对应的最大宽度),在最后才能入栈,此时入栈的元素的h更新为枚举出来的最大宽度 
			LL width = 0;
			while(!stk.empty()&& h[i] <= h[j]) {
				width += a[j];
				maxmum = max(maxmum,h[j] * width);
				stk.pop();
				j = stk.top();
			}
			stk.push(i);
			a[i] += width; 
		}
	}
	printf("%lld\n",maxmum);
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值