P1901 发射站 - 洛谷

P1901 发射站 - 洛谷

题目描述

某地有 N N N 个能量发射站排成一行,每个发射站 i i i 都有不相同的高度 H i H_i Hi,并能向两边(两端的发射站只能向一边)同时发射能量值为 V i V_i Vi 的能量,发出的能量只被两边最近的且比它高的发射站接收。显然,每个发射站发来的能量有可能被 0 0 0 1 1 1 2 2 2 个其他发射站所接受。

请计算出接收最多能量的发射站接收的能量是多少。

输入格式

1 1 1 行一个整数 N N N

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

输出格式

输出仅一行,表示接收最多能量的发射站接收到的能量值。答案不超过 32 位带符号整数的表示范围。

样例 #1

样例输入 #1

3
4 2 
3 5 
6 10

样例输出 #1

7

提示

对于 40 % 40\% 40% 的数据, 1 ≤ N ≤ 5000 , 1 ≤ H i ≤ 1 0 5 , 1 ≤ V i ≤ 1 0 4 1\le N\le 5000,1\le H_i\le 10^5,1\le V_i\le 10^4 1N5000,1Hi105,1Vi104

对于 70 % 70\% 70% 的数据, 1 ≤ N ≤ 1 0 5 , 1 ≤ H i ≤ 2 × 1 0 9 , 1 ≤ V i ≤ 1 0 4 1\le N\le 10^5,1\le H_i\le 2\times 10^9,1\le V_i\le 10^4 1N105,1Hi2×109,1Vi104

对于 100 % 100\% 100% 的数据, 1 ≤ N ≤ 1 0 6 , 1 ≤ H i ≤ 2 × 1 0 9 , 1 ≤ V i ≤ 1 0 4 1\le N\le 10^6,1\le H_i\le 2\times 10^9,1\le V_i\le 10^4 1N106,1Hi2×109,1Vi104

题解

考察单调栈,本题很好地体现了单调栈的性质。

因为对于某一个发射站,其发射的能量只能被高度更高的站中,距离它最近的站吸收,显然这存在着单调栈问题的特征——「截断

这种「截断」的性质,被我们利用后就成为了单调栈中的「单调性」,在入栈和出栈的维护中体现为「截断」

首先,单调性和高度有关,我们维护栈中发射站高度的单调性。

因为在栈中,发射站A的能量会被离他最近,靠近栈顶方向的发射站B吸收,发射站B之后靠近栈顶方向的发射站就接收不到发射站A的能量贡献了,所以这时发射站A可以移除,因此我们要实现这种特征。

假定要入栈的发射站称作新站。

  • 入栈时,如果新站高度大于栈顶(题目保证所有站高度不等),那么栈顶元素对新站之后的所有元素都没有贡献,于是将其出栈,这样将所有高度小于新站的元素出栈。

  • 入栈后,如果栈中新站之前(靠栈底方向)还有一个更高的站,那么新站要向“高站”传输能量

还有1个坑点:需要开3个数组,分别记录高度、发射的能量值,吸收的能量值,然后栈中存储能量站的下标。因为出栈后栈发射站之间的位置关系就变了

#include <algorithm>
#include <iostream>
#include <stack>
using namespace std;
using LL = long long;
const int N = 1e6 + 1;
int n;
LL h[N], v[N], energy[N];
stack<int> stk;
int main() {
    cin >> n;
    for (int i = 1; i <= n; i++)
        cin >> h[i] >> v[i];
    for (int i = 1; i <= n; i++) {
        while (!stk.empty() && h[stk.top()] < h[i]) {
            energy[i] += v[stk.top()];
            stk.pop();
        }
        if (!stk.empty())
            energy[stk.top()] += v[i];
        stk.emplace(i);
    }
    cout << *max_element(energy + 1, energy + 1 + n);
    return 0;
}
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
单调栈是一种特殊的栈结构,它的主要应用是用于解决求某个元素的左边或右边第一个比它大或小的元素的问题。单调栈的特点是栈中的元素保持有序,即栈顶元素最小或最大。而发射站是一个具体的应用场景,我们可以利用单调栈来解决相关问题。 在一个发射站中,我们需要找到每个位置的第一个比它大的位置。我们可以使用单调栈来实现这个功能。首先,我们将第一个元素的下标入栈。然后,依次遍历剩下的每个元素。对于每个元素,我们将它与栈顶元素进行比较。如果当前元素比栈顶元素大,说明找到了以栈顶元素为高度的发射站,我们可以更新它对应的输出结果,并弹出栈顶元素。直到当前元素小于或等于栈顶元素,我们将当前元素的下标入栈。这样,最后栈中剩下的元素对应的输出结果为-1,表示没有找到比它大的位置。 使用单调栈来解决发射站问题的时间复杂度为O(n),其中n为发射站的个数。这是因为每个元素最多入栈一次,出栈一次,所以遍历所有元素的时间复杂度为O(n)。而每个元素入栈和出栈的操作时间复杂度为O(1)。因此,总的时间复杂度为O(n)。 综上所述,利用单调栈结构可以高效地解决发射站问题。通过遍历发射站中的元素,可以找到每个位置的第一个比它大的位置。这种方法的时间复杂度为O(n),其中n为发射站的个数。因此,使用单调栈是一个有效的解决方案。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值