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

    题意:
    题意:n个数,求某段区间的最小值*该段区间所有元素之和的最大值
    思路:
    主要参考:http://www.cnblogs.com/ziyi–caolu/archive/2013/06/23/3151556.html
    首先我们假设第i个元素是最小的话,那么他的区间是确定的,所以值也是确定的。
    然后就是利用栈(单调栈),对于每个位置,搞一个前最远,后最远,然后出栈更新,再入栈。
    感觉就是个利用栈,并且维护这个栈是从栈顶到栈底是单调递增的,存了起来操作。当不是单调递增的时候,栈里的值比他小的就要拿出来,让他更新,然后还要当前栈顶和刚刚拿出来的next更新,具体看代码;
    PS:G++AC,C++TLE;

    //#include <bits/stdc++.h>
    #include<cstdio>
    #include<stack>
    #include<algorithm>
    using namespace std;
    
    typedef long long LL;
    const int N=1e5+10;
    
    struct asd{
        LL pre;
        LL num;
        LL next;
        LL k;
    };
    int n;
    stack<asd>q;
    LL str[N],t[N];
    
    int main()
    {
        while(!q.empty())
            q.pop();
        LL ans=-1;
        LL sum=-1;
        LL num;
        asd tmp;
        scanf("%d",&n);
        str[0]=0;
        for(int i=1;i<=n;i++)
        {
            scanf("%lld",&t[i]);
            str[i]=str[i-1]+t[i];
        }
        tmp.num=t[1];
        tmp.pre=tmp.next=1;
        tmp.k=1;
        q.push(tmp);
        LL x=0,y=0;
        for(LL i=2;i<=n;i++)
        {
            asd tmp1;
            tmp1.num=t[i];
            tmp1.pre=tmp1.next=1;
            tmp1.k=i;
            while(!q.empty()&&tmp1.num<=q.top().num)//如果说这个元素是小于栈顶的,那么它里面的栈就要被更新,这个元素的pre也要被更新
            {
                tmp=q.top();
                q.pop();
                if(!q.empty())
                    q.top().next+=tmp.next;
                tmp1.pre+=tmp.pre;
                ans=tmp.num*(str[tmp.k+tmp.next-1]-str[tmp.k-tmp.pre]);
                if(ans>=sum)
                {
                    sum=ans;
                    x=tmp.k-tmp.pre+1;
                    y=tmp.k+tmp.next-1;
                }
            }
            q.push(tmp1);
        }
        while(!q.empty())
        {
            tmp=q.top();
            q.pop();
            if(!q.empty())
                q.top().next+=tmp.next;
            ans=tmp.num*(str[tmp.k+tmp.next-1]-str[tmp.k-tmp.pre]);
            if(ans>=sum)
            {
                sum=ans;
                x=tmp.k-tmp.pre+1;
                y=tmp.k+tmp.next-1;
            }
        }
        printf("%lld
    %lld %lld
    ",sum,x,y);
        return 0;
    }
    
    
    
  • 相关阅读:
    hexo命令报错
    开始使用hexo
    javascript 获取元素
    javascript DOM属性操作
    javascript DOM节点操作
    javascript 完美拖动效果
    ubuantu 18.04 LTS 版本解决网易云安装启动问题
    课后作业-阅读任务-阅读提问-3
    C# 并行循环
    C# 委托
  • 原文地址:https://www.cnblogs.com/keyboarder-zsq/p/5934812.html
Copyright © 2011-2022 走看看