题解:洛谷 P1901 发射站

【题目来源】

洛谷:P1901 发射站 - 洛谷

【题目描述】

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

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

【输入】

\(1\) 行一个整数 \(N\)

\(2\)\(N+1\) 行,第 \(i+1\) 行有两个整数 \(H_i\)\(V_i\),表示第 \(i\) 个发射站的高度和发射的能量值。

【输出】

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

【输入样例】

3
4 2 
3 5 
6 10

【输出样例】

7

【算法标签】

《洛谷 P1901 发射站》 #栈# #单调栈# #NOI导刊#

【代码详解】

#include <bits/stdc++.h>
using namespace std;
const int N = 1000005;
int n, h[N], v[N];  // n: 数量,h[i]: 第i个塔的高度,v[i]: 第i个塔的能量
int sum[N];  // sum[i]: 第i个塔最终获得的总能量
int q[N];  // 单调栈,存储塔的编号

int main()
{
    cin >> n;  // 读入塔的数量
    
    for (int i = 1; i <= n; i++)
    {
        cin >> h[i] >> v[i];  // 读入每个塔的高度和能量
    }
    
    int top = 0;  // 栈顶指针
    for (int i = 1; i <= n; i++)  // 从左到右处理每个塔
    {
        // 维护单调递减栈:当栈顶塔比当前塔矮时
        while (top && h[q[top]] < h[i])
        {
            // 栈顶塔的能量会流向当前塔i
            sum[i] += v[q[top--]];  // 栈顶的能量给i,然后弹出
        }
        
        // 如果栈不为空,说明当前塔i的能量会流向栈顶塔
        if (top)
        {
            sum[q[top]] += v[i];  // i的能量给栈顶塔
        }
        
        q[++top] = i;  // 当前塔i入栈
    }
    
    int ans = 0;
    for (int i = 1; i <= n; i++)
    {
        ans = max(ans, sum[i]);  // 找出获得能量最多的塔
    }
    
    cout << ans;  // 输出最大能量
    return 0;
}
// 使用acwing模板二刷
#include <bits/stdc++.h>
using namespace std;
const int N = 1000005;
int n, h[N], v[N], sum[N], stk[N], tt;  // n: 塔的数量,h: 塔的高度,v: 塔的能量,sum: 塔接收的总能量,stk: 单调栈,tt: 栈顶指针

int main()
{
    cin >> n;  // 读入塔的数量
    
    for (int i = 1; i <= n; i++)
    {
        cin >> h[i] >> v[i];  // 读入每个塔的高度和能量
    }
    
    for (int i = 1; i <= n; i++)  // 从左到右遍历每个塔
    {
        // 维护单调递减栈:当栈顶塔比当前塔i矮时
        while (tt && h[stk[tt]] < h[i])
        {
            // 栈顶塔的能量会流向当前塔i
            sum[i] += v[stk[tt]];  // 栈顶塔的能量累加到塔i
            tt--;  // 弹出栈顶
        }
        
        // 如果栈不为空,当前塔i的能量会流向栈顶塔
        sum[stk[tt]] += v[i];  // 塔i的能量累加到栈顶塔
        
        stk[++tt] = i;  // 当前塔i入栈
    }
    
    int ans = 0;
    for (int i = 1; i <= n; i++)
    {
        ans = max(ans, sum[i]);  // 找出获得最大能量的塔
    }
    
    cout << ans;  // 输出最大能量值
    return 0;
}

【运行结果】

3
4 2
3 5
6 10
7
posted @ 2026-03-14 21:45  团爸讲算法  阅读(2)  评论(0)    收藏  举报