官方题解
2026-03-30 15:52:07
发布于:浙江
12阅读
0回复
0点赞
题目大意
从位置 出发,要到达位置 。初始有能量 ,每走 单位距离消耗 能量。沿途有若干补给站,第 个补给站在位置 ,可以提供 的能量,每个站最多使用一次。求最少需要使用多少个补给站才能到达终点,若无法到达输出 。
题解思路
这是一个典型的贪心问题。关键在于:当当前能量不足以继续前进时,应该从之前经过的所有补给站中选择补给量最大的那个来使用。
先将所有补给站按位置排序,并把终点看成一个位置为 、补给量为 的虚拟站。设当前最远能到达的位置为 ,初始为 ,同时用一个大根堆维护所有已经经过的补给站的补给量。
从左到右扫描每个站:
如果当前站的位置 ,说明可以到达,就把该站的补给量加入堆中;如果 ,说明当前无法到达这个站,此时必须从堆中取出最大补给量来补充能量,使 增大,并统计一次补给操作。重复这个过程,直到可以到达当前站或者堆为空。
如果堆为空仍无法前进,说明无法到达终点,输出 。否则最终成功走到终点,补给次数就是答案。
这个贪心策略的核心在于:每次必须补给时,选择补给量最大的站,可以让当前可达距离尽可能远,从而减少后续补给次数,是最优选择。
参考代码
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
struct Node {
ll x;
ll a;
};
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
int n;
ll L, P;
cin >> n >> L >> P;
vector<Node> s(n + 1);
for (int i = 0; i < n; ++i) {
cin >> s[i].x >> s[i].a;
}
s[n] = {L, 0};
sort(s.begin(), s.end(), [](const Node& u, const Node& v) {
return u.x < v.x;
});
priority_queue<ll> q;
ll reach = P;
int ans = 0;
for (int i = 0; i <= n; ++i) {
while (reach < s[i].x) {
if (q.empty()) {
cout << -1 << '\n';
return 0;
}
reach += q.top();
q.pop();
++ans;
}
q.push(s[i].a);
}
cout << ans << '\n';
return 0;
}
这里空空如也








有帮助,赞一个