zoukankan      html  css  js  c++  java
  • HDU 1506【单调栈】

    思路:
    转化成对于某一位置为最小值求向两边最远>=他的位置,用单调栈就能轻易完成。
    那么ans=(left+right)*h[i];
    维护单调递增还是递减呢?
    我们能很快反应到,一旦碰到一个比他小的元素,那么之前的那个比他大的就要结束了。
    ok,大致了解到碰到比他小的元素,那么比他大的呢?
    也简单呀,对于比他大的元素,左端点已经找到了呀!
    那么基于双方考虑,是不是就是维护单调递增栈呢?
    如果碰到比top值大的,那么就压栈,并且左端点为i-1;
    如果遇到比top值小的,要把栈里面值比他大的全部输出,因为已经找到右端点 i 了。
    这么理解记忆还是略累啊。。。我就是如果我要以他为最小值两边延伸,那么就维护增,记忆成相反的。
    而且比较喜欢用结构体表示一个结点所有信息,仅供参考吧~


    //#include <bits/stdc++.h>
    #include <iostream>
    #include <stack>
    #include <cstdio>
    #include <cstring>
    #include <cmath>
    #include <algorithm>
    #include <queue>
    #include <vector>
    #include <map>
    using namespace std;
    typedef long long LL;
    typedef pair<int,int> PII;
    const int N=1e5+10;
    struct asd
    {
        LL left,right;
        LL w;
    };
    LL h[N];
    LL n;
    stack<asd>q;
    int main()
    {
        while(~scanf("%I64d",&n)&&n)
        {
            asd now,nex;
            while(!q.empty())
                q.pop();
            for(int i=1; i<=n; i++)
                scanf("%I64d",&h[i]);
            LL ans=h[1];
            now.left=0;
            now.right=1;
            now.w=h[1];
            q.push(now);
            for(int i=2; i<=n; i++)
            {
                now.left=0;
                now.right=1;
                now.w=h[i];
                while(!q.empty()&&q.top().w>h[i])
                {
                    nex=q.top();
                    q.pop();
                    now.left+=(nex.left+1);
                    LL temp=(nex.left+nex.right)*nex.w;
                    ans=max(ans,temp);
                    if(!q.empty())
                        q.top().right+=nex.right;
                }
                q.push(now);
            }
            while(!q.empty())
            {
                nex=q.top();
                q.pop();
                LL temp=(nex.left+nex.right)*nex.w;
                ans=max(ans,temp);
                if(!q.empty())
                    q.top().right+=nex.right;
            }
            printf("%I64d
    ",ans);
        }
        return 0;
    }


  • 相关阅读:
    ssm之spring+springmvc+mybatis整合初探
    mybatis缓存之整合第三方缓存工具ehcache
    mybatis缓存之二级缓存
    mybatis缓存之一级缓存
    mybatis动态sql之利用sql标签抽取可重用的sql片段
    mybatis动态sql之bind标签
    mybatis动态sql之内置参数_parameter和_databaseId
    mybatis动态sql之使用foreach进行批量插入的两种方式
    mybatis动态sql之foreach补充(三)
    Visitor Pattern
  • 原文地址:https://www.cnblogs.com/keyboarder-zsq/p/6777411.html
Copyright © 2011-2022 走看看