zoukankan      html  css  js  c++  java
  • 单调栈、单调队列 思路及例题

    单调栈

    单调栈目的并不在于存储所有入栈元素。

    对于一个单调递增栈,如果栈为空或入栈元素值小于栈顶元素值,则入栈;

    否则,如果入栈则会破坏栈的单调性,则需要把比入栈元素小的元素全部出栈。

    单调递减栈反之同理。

    及时排除不可能的选项,保持策略集合的高度有效性和秩序性

    时间复杂度 (O(n))。(每个元素至多入栈一次,出栈一次。)


    以下是模板题:


    [USACO06NOV] Bad Hair Day

    (试题来源:Link link

    Description

    Some of Farmer John's (N) cows ((1 ≤ N ≤ 80,000)) are having a bad hair day! Since each cow is self-conscious about her messy hairstyle, FJ wants to count the number of other cows that can see the top of other cows' heads.

    Each cow (i) has a specified height (h_i) ((1 ≤ h_i ≤ 1,000,000,000)) and is standing in a line of cows all facing east (to the right in our diagrams). Therefore, cow (i) can see the tops of the heads of cows in front of her (namely cows (i+1), (i+2), and so on), for as long as these cows are strictly shorter than cow (i).

    Consider this example:

            =
    =       =
    =   -   =         Cows facing right -->
    =   =   =
    = - = = =
    = = = = = =
    1 2 3 4 5 6 
    

    Cow#1 can see the hairstyle of cows #2, 3, 4

    Cow#2 can see no cow's hairstyle

    Cow#3 can see the hairstyle of cow #4

    Cow#4 can see no cow's hairstyle

    Cow#5 can see the hairstyle of cow 6

    Cow#6 can see no cows at all!

    Let (c_i) denote the number of cows whose hairstyle is visible from cow (i); please compute the sum of (c_1) through (c_N). For this example, the desired is answer (3 + 0 + 1 + 0 + 1 + 0 = 5).

    Input

    Line (1): The number of cows, (N).

    Lines (2..N+1): Line (i+1) contains a single integer that is the height of cow (i).

    Output

    Line (1): A single integer that is the sum of (c_1) through (c_N).

    Sample Input

    6
    10
    3
    7
    4
    12
    2
    

    Sample Output

    5
    

    单调递增栈。当原栈顶元素被踢出栈,说明原栈顶元素的右边存在更大的元素(也就是 (i)),此时统计答案。新建一个超大元素,用于在最后把所有栈内剩余元素踢出。

    /* [USACO06NOV] Bad Hair Day
     * Au: GG
     */
    #include <cstdio>
    const int N=80003, inf=1e9+3;
    int n, cow[N]; long long ans;
    int s[N], t;
    
    int main() {
        scanf("%d", &n);
        for (int i=1; i<=n; ++i) scanf("%d", &cow[i]);
        cow[n+1]=inf;
        for (int i=1; i<=n+1; ++i) {
            if (t && cow[i]>=cow[s[t]])
                while (t && cow[i]>=cow[s[t]])
                    ans += i-s[t]-1, --t;
            s[++t]=i;
        }
        printf("%lld
    ", ans);
        return 0;
    }
    

    单调队列

    我们只需要维护对头(最值)元素,所以其他对答案无贡献的元素可以直接删去。

    对于一个单调递增队列,维护队头、队尾,队尾元素只要大于新添加的元素一律删去。

    单调递减队列同理。

    在决策集合中及时排除一定不是最优解的选择,保持高度有效性和秩序性。

    时间复杂度 (O(n))。(每个元素至多入队一次,出队一次。)


    模板题可参考 http://www.cnblogs.com/greyqz/p/9521630.html




    Post author 作者: Grey
    Copyright Notice 版权说明: Except where otherwise noted, all content of this blog is licensed under a CC BY-NC-SA 4.0 International license. 除非另有说明,本博客上的所有文章均受 知识共享署名 - 非商业性使用 - 相同方式共享 4.0 国际许可协议 保护。
  • 相关阅读:
    IntelliJ IDEA 常用快捷键和设置
    Code Project精彩系列(2)
    Code Project精彩系列(2)
    Code Project精彩系列(2)
    Apache和Tomcat区别
    Apache和Tomcat区别
    Apache和Tomcat区别
    如何在 GitHub 建立个人主页和项目演示页面
    如何在 GitHub 建立个人主页和项目演示页面
    如何在 GitHub 建立个人主页和项目演示页面
  • 原文地址:https://www.cnblogs.com/greyqz/p/9536639.html
Copyright © 2011-2022 走看看