• 单调栈


    题目:地上从左到右竖立着 n 块木板,从 1 到 n 依次编号,如下图所示。我们知道每块木板的高度,在第 n 块木板右侧竖立着一块高度无限大的木板,现对每块木板依次做如下的操作:对于第 i 块木板,我们从其右侧开始倒水,直到水的高度等于第 i 块木板的高度,倒入的水会淹没 ai 块木板(如果木板左右两侧水的高度大于等于木板高度即视为木板被淹没),求 n 次操作后,所有 ai 的和是多少。如图上所示,在第 4 块木板右侧倒水,可以淹没第 5 块和第 6 块一共 2 块木板,a4 = 2。

    分析:当水往右边蔓延遇到了一块高度大于等于 hi 的木板 j,ai 就等于木板 i 和木板 j 之间的木板数。于是,问题就变成了寻找在第 i 个数右边第一个比它大的数。可以用单调栈来解决。


    代码

    #include<iostream>
    #include<cassert>
    using namespace std;
    class Node {
    public:
        int id, height;
    };
    template<class Type> class Stack {
    private:
        Type *urls;
        int max_size, top_index;
    public:
        Stack(int length_input) {
            urls = new Type[length_input];
            max_size = length_input;
            top_index = -1;
        }
        ~Stack() {
            delete[] urls;
        }
        bool push(const Type &element) {
            if (top_index >= max_size - 1) {
                return false;
            }
            top_index++;
            urls[top_index] = element;
            return true;
        }
        bool pop() {
            if (top_index < 0) {
                return false;
            }
            top_index--;
            return true;
        }
        Type top() {
            assert(top_index >= 0);
            return urls[top_index];
        }
        bool empty() {
            if (top_index < 0) {
                return true;
            } else {
                return false;
            }
        }
    };
    int main() {
        int n,ans=0;
        cin>>n;
        Stack<Node>stack(n);
        Node temp;
        for(int i=1;i<=n;i++){
            cin>>temp.height;
            temp.id=i;
            while(!stack.empty()&&stack.top().height<=temp.height){
                ans=ans+i-stack.top().id-1;
                stack.pop();
            }
            stack.push(temp);
        }
        while(!stack.empty()){
            ans=ans+n+1-stack.top().id-1;
                stack.pop();
        }
        cout<<ans<<endl;
        return 0;
    }

  • 相关阅读:
    Jmeter属性和变量
    用trie树解决最大异或对问题(On)
    trie树
    kmp算法
    数学归纳法
    单调栈和单调队列
    区间合并
    离散化
    位运算
    双指针算法
  • 原文地址:https://www.cnblogs.com/nickqiao/p/7583365.html
Copyright © 2020-2023  润新知