zoukankan      html  css  js  c++  java
  • 浅谈单调栈的实现方式和简单应用

    一、单调栈的原理和实现方式

    1.定义

    从栈底元素到栈顶元素呈单调递增或单调递减,栈内序列满足单调性的栈;

    2.原理

    (1)当新元素在单调性上优于栈顶时(单增栈新元素比栈顶大,单减栈新元素比栈顶小),压栈,栈深+1;

    (2)当新元素在单调性与栈顶相同(新元素于栈顶相同)或劣于栈顶时(单增栈新元素比栈顶小,单减栈新元素比栈顶大),弹栈,栈深-1;

    3.一般实现形式

    以单增栈(栈顶为最大值)为例:

    n为元素数,h为入栈序列,tot为栈深,stack为单增栈;

    void stacks(){
            int stack[10001],tot=0,n,h;
            memset(stack,0,sizeof(stack));
            scanf("%d",&n);
            for(i=1;i<=n;++i){
                    scanf("%d",&h);
                    while(tot>0&&h<=stack[tot]) --tot;
                    stack[++tot]=h;
            }
    }
    

    4.几点注意

    (1)在弹栈过程中,注意增加限制条件tot>0,若无此条件,如果新元素为负数,弹栈过程中就可能出现tot<0的现象;

    (2)在弹栈压栈过程中,注意随时更新栈深;

    (3)多次使用时没必要每次都重置栈,有操作流程知数据直接覆盖不会出现问题,可以节省时间;

    二、相关应用

    下面我们通过由简到难介绍几个题目来说明单调栈的使用方式:

    1.[模板]最长上升子序列 (LIS)

    Description

    给一个数组 a[1],a[2],...,a[n],找到最长的上升子序列a[b1]< a[b2]< ... < a[bk]的长度,其中b[1]<b[2]< ... <b[k]。

    Solution

    1.用单调栈优化,利用LIS的单调性,使用单增栈,栈顶为最大值;

    2.对于每一个数:

    (1)当其大于栈顶时,满足单调性,压栈;

    (2)当其小于栈顶时,不满足单调性,向下搜索大于该数的最小值,替换;

    (3)当其等于栈顶时,不满足单调性,不作处理;

    3.栈深即为LIS的长度;

    Code

    #include<cstdio>
    #include<iostream>
    #include<cmath>
    #include<cstring> 
    #include<algorithm>
    using namespace std;
    
    int a[1005],b[1005],n;
    int stk[1005];
    
    int main(){
    	scanf("%d",&n);
    	for(int i=1;i<=n;i++) scanf("%d",&a[i]),b[i]=a[i];	
    	sort(b+1,b+n+1);
    	int tot=unique(b+1,b+n+1)-(b+1);
    	for(int i=1;i<=n;i++) a[i]=lower_bound(b+1,b+tot+1,a[i])-b;
    	int top=0;
    	for(int i=1;i<=n;i++){
    		if(top==0||stk[top-1]<a[i]) stk[top++]=a[i];
    		else{
    			*upper_bound(stk,stk+top,a[i])=a[i];
    		}
    	}
    	printf("%d
    ",top);
    	return 0;	
    }
    

    2.[洛谷P1823]音乐会的等待

    题解随笔:http://www.cnblogs.com/COLIN-LIGHTNING/p/8486447.html

    3.[POI 2008&洛谷P3467]PLA-Postering

    题解随笔:http://www.cnblogs.com/COLIN-LIGHTNING/p/8480054.html

    4.[POJ 2559]Largest Rectangle in a Histogram

    题解随笔:http://www.cnblogs.com/COLIN-LIGHTNING/p/8480091.html

    5.[洛谷P4147&BZOJ 3039]玉蟾宫

    题解随笔:http://www.cnblogs.com/COLIN-LIGHTNING/p/8480130.html

  • 相关阅读:
    Python中获取异常(Exception)信息
    python中的构造函数和析构函数
    windows下python检查文件是否被其它文件打开
    python怎样压缩和解压缩ZIP文件
    Python递归遍历《指定目录》下的所有《文件》
    HTML基础知识(w3school)
    关于c#除法运算的问题
    WPF如何给窗口Window增加阴影效果
    图片加载,创建事件监听
    版本回退的冲突问题
  • 原文地址:https://www.cnblogs.com/COLIN-LIGHTNING/p/8474668.html
Copyright © 2011-2022 走看看