洛谷 P1901 发射站 题解

P1901 发射站

题目描述

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

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

输入格式

第 1 行:一个整数 N;

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

输出格式

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

输入输出样例

输入 #1

3
4 2
3 5
6 10

输出 #1

7

说明/提示

对于 40%的数据,1<=N<=5000;1<=Hi<=100000;1<=Vi<=10000;

对于 70%的数据,1<=N<=100000;1<=Hi<=2,000,000,000;1<=Vi<=10000;

对于 100%的数据,1<=N<=1000000;1<=Hi<=2,000,000,000;1<=Vi<=10000。

【思路】

单调栈板子题
(下文中的信号都是能量的意思,感觉说发射信号比发射能量更有意思)

【题目大意】

很多根信号塔
信号塔可以发射信号
发射的信号只有两边第一个比他高的信号塔才能够接收到

【为什么要用单调栈】

单调栈是用来求一个点两边最早大于或者小于的点的位置的
这很显然对吧
因为你在那这个数和栈顶比较的时候
(假设目前再找两边第一个高于这个点的
和题目要求一样)
如果这个数大于栈顶
那很显然栈顶右边第一个大于他的数找到了是的吧
然后如果这个数小于栈顶
那很显然这个数左边第一个大于他的数也找到了是的吧
所以单调栈是可以用来求两边第一个大于/小于这个数的位置的

【最后思路】

用单调栈找出两边第一个大于这个数的位置
在单调栈单调的过程中
上面说的如果这个数大于栈顶
那这个位置的信号塔收到的信号就可以加上栈顶能够发出的信号
如果这个数小于栈顶
那这个位置的信号塔发出的信号就能够被栈顶所在的那个信号塔收到
所以栈顶所在的信号塔能够收到的信号
就加上这个数所在的信号塔能够发出的信号强度
最后枚举一遍每一个电线杆子收到的信号
比较最大值输出就okoj了

【完整代码】

#include<iostream>
#include<cstdio>
#include<stack>
using namespace std;
const int Max = 1000006;
struct node
{
    int hao;
    int h;
    int v;
    int w;
}a[Max];
stack<int>s;
int main()
{
    int n;
    cin >> n;
    for(register int i = 1;i <= n;++ i)
        cin >> a[i].h >> a[i].v,a[i].hao = i;
    for(register int i = 1;i <= n;++ i)
    {
        while(!s.empty() && a[s.top()].h < a[i].h)
        {
            a[i].w += a[s.top()].v;
            s.pop();
        }
        if(!s.empty())
        a[s.top()].w += a[i].v;
        s.push(i);
    }
    int M = 0;
    for(register int i = 1;i <= n;++ i)
        M = max(M,a[i].w);
    cout << M << endl;
    return 0; 
}

猜你喜欢

转载自www.cnblogs.com/acioi/p/11681307.html