首页 > 其他分享 >单调栈

单调栈

时间:2023-02-02 15:44:06浏览次数:56  
标签:矩形 int tt ++ -- include 单调

顾名思义单调栈就是具有单调性的栈

常见模型:找出每个数左边离它最近的比它大/小的数

  1. 【算法】
int stk[N],tt = 0;	// 栈中存数据
for (int i = 1; i <= n; i ++){
    int x; cin >> x;
    while (tt && stk[tt] >= x) tt -- ;	// 左边比它小的数
    stk[ ++ tt] = i;	// 把当前值放在合适地方
}
  1. 【应用一】
    直方图中最大的矩形
    算法思想:
    ① 以每一个矩形的高为标准,找出左右两边第一个小于此矩形高的矩形,枚举所有
    的矩形,找出最大面积。
    ② 利用单调栈,进行预处理将每个矩形左右两边的第一个小于此矩形高的矩形。
#include <iostream>
#include <vector>
#include <cstring>
#include <algorithm>

using namespace std;
typedef long long LL;
const int N = 100010;
int n;// h: 高度 q: 单调栈->记录h的下标 l: 左边符合条件距离 r: 右边符合条件距离
int h[N],q[N],l[N],r[N];
void solve(){
    while (scanf("%d", &n),n){
        for (int i = 1; i <= n; i ++) scanf("%d",&h[i]);
        h[0] = h[n + 1] = -1;      // 预处理要边界条件
        // 找出左边第一个高度小于当前
        int tt = -1;
        q[++ tt] = 0;   // 下标 0
        for (int i = 1; i <= n; i ++){
            while (h[q[tt]] >= h[i]) tt --;//维护好单调栈: 找到栈中第一个小于当前值的数据
            l[i] = i - q[tt];   // 记录i左边第一符合条4 件的数据距离
            q[++ tt] = i;       // 当前值下标入栈
        }
        // 同理求右边
        tt = -1;
        q[++ tt] = n + 1;
        for (int i = n; i >= 1; i --){
            while (h[q[tt]] >= h[i]) tt --;
            r[i] = q[tt] - i;
            q[++ tt] = i;
        }
        LL res = 0;
        for (int i = 1; i <= n; i ++)
            res = max(res, (LL)h[i] * (l[i] + r[i] - 1));// - 1是因为计算左右两边就多加一个h[i]
        printf("%lld\n", res);
    }
}
int main(){
    solve();
    return 0;
}
  1. 【应用二】
    城市游戏
    算法思想:
    联想【应用一】,统计每一行向上的高度,再利用应用一单调栈的解题方法,遍历n行,求出最优解。
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long LL;
typedef pair<int,int> PII;

const int N = 1010;
int n,m,res;
int h[N],q[N],l[N],r[N];
// 这里就是【应用一】一行的解题方法
void solve(){
    for (int i = 0; i <= m + 1; i ++)q[i] = 0;
    h[0] = h[m + 1] = -1;
    int tt = -1;
    q[++ tt] = 0;
    for (int i = 1; i <= m; i ++){
        while (h[q[tt]] >= h[i]) tt --;
        l[i] = i - q[tt];
        q[++ tt] = i;
    }
    tt = -1;
    q[++ tt] = m + 1;
    for (int i = m; i >= 1; i --){
        while (h[q[tt]] >= h[i]) tt --;
        r[i] = q[tt] - i;
        q[++ tt] = i;
    }
    for (int i = 1; i <= m; i ++)
        res = max(res, h[i] * (l[i] + r[i] - 1));
}
int main(){
    cin >> n >> m;
    for (int i = 0; i < n; i ++){
        for (int j = 1; j <= m; j ++){
            char c; cin >> c;   // 这里建议用cin 自动省略空格回车
            if (c == 'R') h[j] = 0;  // 遇R高度就变0
            else h[j] += 1;
        }
        solve();
    }
    printf("%d\n", res * 3);
    return 0;
}

标签:矩形,int,tt,++,--,include,单调
From: https://www.cnblogs.com/sxy666666/p/17085933.html

相关文章

  • 单调栈及其应用
    目录单调栈简介伪代码应用应用1:Leetcode.496题目分析代码实现复杂度分析应用2:Leetcode.503题目分析代码实现应用4:Leetcode.2454题目分析代码实现应用4:Leetcode.739题目分析......
  • 堆栈、队列、单调栈、单调队列1
    Stack和Queue——栈和队列栈的定义:栈是限定仅在表头进行插入和删除操作的线性表(先进后出)队列的定义:队列是一种特殊的线性表,特殊之处在于它只允许在表的前端(front)......
  • 两个单调栈的问题
    两个单调栈的问题写灵神每日,遇到两个单调栈的经典问题,就放一起了问题一https://codeforces.com/problemset/problem/1691/D输入t(≤1e5)表示t组数据,每组数据输入n......
  • P5858 「SWTR-03」Golden Sword DP+单调队列模板
    P5858「SWTR-03」GoldenSword-洛谷|计算机科学教育新生态(luogu.com.cn) 理解题意后,我们知道贪心和暴力枚举显然是不行的,联想到DP我们设置dp[i][j]表示,第i种......
  • 【算法】单调栈 & 单调队列学习笔记
    1.单调栈简介1.1前言今天是2023/1/15,一中寒假集训阶段性的结束了。集训的学习笔记可以在本人blogs的【算法】标签栏中找。马上就要过年了,提前祝大家新年快乐!1.2......
  • 单调队列详解
    简介单调栈和单调队列都是思维难度比较大的数据结构,但只要想明白了就会觉得很简单。要理解单调队列,首先得明白“单调”是指它存储的内容单调,而不是指它简单。实现模板......
  • 单调栈详解
    简介单调栈和单调队列都是思维难度比较大的数据结构,但是比较幸运,这些数据结构能出的题不多,只有几个板子。要理解单调栈,首先得明白“单调”是只它存储的内容单调,不是说它......
  • 单调栈
    单调栈与普通栈的区别同样作为一种FILO(后进先出)的数据结构,单调栈在普通栈的基础上增加了一个要求:栈内元素必须严格单调递增或单调递减栈顶到栈底严格递增的栈叫单......
  • 单调栈
    单调栈和单调队列通常的做法,用栈或者队列来存储元素,用栈和队列来考虑暴力的模拟方法,然后观察栈和队列里面的元素,看看是否有一些元素完全没用,把这些元素删掉,看看剩余元素是......
  • P1886 滑动窗口 /【模板】单调队列
    滑动窗口/【模板】单调队列题目描述有一个长为\(n\)的序列\(a\),以及一个大小为\(k\)的窗口。现在这个从左边开始向右滑动,每次滑动一个单位,求出每次滑动后窗口中的......