luogu_P1901 发射站

https://www.luogu.org/problem/P1901

题目描述

某地有 N 个能量发射站排成一行,每个发射站 i 都有不相同的高度 Hi,并能向两边(当 然两端的只能向一边)同时发射能量值为 Vi 的能量,并且发出的能量只被两边最近的且比 它高的发射站接收。

显然,每个发射站发来的能量有可能被 0 或 1 或 2 个其他发射站所接受,特别是为了安 全,每个发射站接收到的能量总和是我们很关心的问题。由于数据很多,现只需要你帮忙计 算出接收最多能量的发射站接收的能量是多少。

输入格式

第 1 行:一个整数 N;

第 2 到 N+1 行:第 i+1 行有两个整数 Hi 和 Vi,表示第 i 个人发射站的高度和发射的能量值。

输出格式

输出仅一行,表示接收最多能量的发射站接收到的能量值,答案不超过 longint。


维护一个元素高度单调下降的栈

从左往右一次,从右往左一次

#include<iostream> 
#include<algorithm>
#include<cstdio>

#define ri register int
#define u int
#define NN 1000005

namespace fast {
    
    inline u in() {
        u x(0),f(1);
        char s=getchar();
        while(s<'0'||s>'9') {
            if(s=='-'){
                f=-1;
            }
            s=getchar();
        }
        while(s>='0'&&s<='9') {
            x=(x<<1)+(x<<3)+s-'0';
            s=getchar();
        }
        return x*f;
    }
    
}

using fast::in;

namespace all {
    
    struct node{
        u h,v;
    }a[NN];
    u stk[NN],r,as,ans[NN];
    
    inline void solve(){
        u N(in());
        for(ri i(1);i<=N;++i){
            a[i].h=in(),a[i].v=in();
        }
        r=0;
        for(ri i(1);i<=N;++i){
            u x(i);
            while(r&&a[stk[r]].h<=a[x].h) --r;
            ans[stk[r]]+=a[x].v;
            stk[++r]=x;
        }
        r=0;
        for(ri i(1);i<=N;++i){
            u x(N-i+1);
            while(r&&a[stk[r]].h<=a[x].h) --r;
            ans[stk[r]]+=a[x].v;
            stk[++r]=x;
        }
        for(ri i(1);i<=N;++i){
            as=std::max(as,ans[i]);
        }
        printf("%d",as);
    }
    
}

int main() {
    
    //freopen("x.txt","r",stdin);
    all::solve();
    
}

猜你喜欢

转载自www.cnblogs.com/ling-zhi/p/11665436.html