码迷,mamicode.com
首页 > 其他好文 > 详细

poj2796

时间:2017-08-31 17:58:09      阅读:222      评论:0      收藏:0      [点我收藏+]

标签:ons   数组   定向   ini   决定   lld   pre   return   斜率优化   

#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\n%d %d\n", value, l, r);
    }
    void show(int i) {
        printf("i = %d %d %d %lld \n", 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;
}

 

poj2796

标签:ons   数组   定向   ini   决定   lld   pre   return   斜率优化   

原文地址:http://www.cnblogs.com/shuly/p/7459332.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!