zoukankan      html  css  js  c++  java
  • poj2796

    #include <cstdio>
    /*
     *  source poj.2796
     *  题目: 
     *      给定一个非负数的数组 其中value[l,r] = sum(l,r) * min (l,r);
     *    求 最大值和,最大值的位置
     *  题解:
     *      所求的区域的最小值是x的话一定是这个值向左右去延伸至比他大的元素为止
     *   而这个问题的求解一般是n^2的问题,但是我们不能接受因此;
     *      维护这个区间需要我们维护一个stack
     *      具体操作如下
     *      (1)元素入栈
     *       1,记录值(value, weight) -> weight 初始是1,value是入栈的值,
     *       2,先让大于等于value的值出栈,并且更新 ANS  [value * weight]   对比决定是否更新.   
     *       3,如果这个栈顶元素也大于等于value, 把出栈的这个值的重量给目前的栈顶元素, 到步骤(2),否则到步骤(4).
     *       4,把这个出栈的重量给 准备入栈的元素.
     *       5,元素入栈
     *   (2)元素全部入栈后 因为还有元素在里面. 剩下的元素逐个出栈,  只不过把这个元素的重量给下一个栈顶元素. 类似与插入-1.
     *       hint:
     *
     *     其实他每次出栈的 就是我们刚开说的那种区间, 以那个元素为做小值向左右扩展得到的区间值.
     *
     *     对于栈顶元素.
     *          一个元素的入栈 会促使 左侧比他大的合并,
     *               而后出栈的时候右侧肯定也都合并到自己身上,因此栈顶元素对于我们所扫描到的位置一定是合法的
     *      栈顶元素肯定向右或者说向左都是达标的;
     *      这是个斜率优化问题. 怀念以前,现在是个弱鸡(ง •̀_•́)ง        
     */
    #define min(x, y) ( (x) < (y) ? (x) : (y) )
    #define max(x, y) ( (x) < (y) ? (y) : (x) )
    const int N = 1e5;
    struct Ans {
        int l, r;
        long long value;
        Ans(){l = r = value = -1;}
        bool operator < (const  Ans & rht ) const {
            return value < rht.value;
        }
        void out(){
            printf("%lld
    %d %d
    ", value, l, r);
        }
        void show(int i) {
            printf("i = %d %d %d %lld 
    ", i, l, r, value);
        }
    };
    struct Info {
        long long h, w;
        int p; 
        Info(){}
        Info(long long _h, long long  _w, int _p):h(_h), w(_w), p(_p) {}
        bool operator < (const Info & rht) const {
            return this -> h < rht.h;
        }
        Info operator + (const Info & rht) const {
            return Info( min(rht.h, this -> h), rht.w + this -> w, this -> p);
        }
    };
    Info stack[N + 7];
    int pos;
    Ans ans;
    inline void init() {
        pos = 0;
        ans = Ans();
    }
    void in(long long tmp, int i) {
        Info inStack = Info(tmp, tmp, i);
        Info key = Info(0x7fffffff, 0, -1);
        while(pos != 0 && stack[pos - 1].h >= inStack.h) {
            key = stack[--pos] + key;
            Ans wps = Ans();
            wps.l       = key.p;
            wps.r       = i - 1;
            wps.value   = (long long )key.w * (long long )key.h;
    
            ans = max(ans, wps);
        }
        if (key.p != -1) {
            inStack = key + inStack;
        }
        stack[pos++] = inStack;
    } 
    int main() {
        int n;
        long long tmp;
        while(~scanf("%d", &n)) {
            init();
            for(int i = 1; i <= n; ++i) {
                scanf("%lld", &tmp);
                in(tmp, i);
            }
            in(0, n + 1);
            ans.out();   
        }
        return 0;
    }
  • 相关阅读:
    SpringMVC项目模块浅析
    利用python脚本(xpath)抓取数据
    利用python脚本(re)抓取美空mm图片
    Intellij idea开发Hadoop MapReduce程序
    在Hadoop平台跑python脚本
    Hadoop常用命令
    CentOS6.5 安装Zookeeper集群
    MySQL常用命令
    MongoDB常用命令
    前后端分离架构+k8s+ingress
  • 原文地址:https://www.cnblogs.com/shuly/p/7459332.html
Copyright © 2011-2022 走看看