贪心,优先级队列。
基本思路:走过一个加油站,先不要加油,把这个油量存到仓库,到油量不够的时候去仓库补油,补油优先选择油量大的。
细节较多,容易写错。
#include<cstdio> #include<cstring> #include<cmath> #include<queue> #include<algorithm> using namespace std; int n; struct Point { long long x; long long sum; }p[100000 + 10]; long long L, P; bool cmp(const Point&a, const Point&b) { return a.x<b.x; } int main() { while (~scanf("%d", &n)) { priority_queue<int>q; for (int i = 1; i <= n; i++) scanf("%lld%lld", &p[i].x, &p[i].sum); scanf("%lld%lld", &L, &P); for (int i = 1; i <= n; i++) p[i].x = L - p[i].x; sort(p + 1, p + 1 + n, cmp); if (p[n].x != L){ p[n + 1].x = L; p[n + 1].sum = 0; n++; } int ans = 0; long long pre = 0; for (int i = 1; i <= n; i++) { long long dis = p[i].x - pre; P = P - dis; if (p[i].x == L&&P >= 0) break; if (p[i].x == L) { while (P < 0 && (!q.empty())) { P = P + q.top(); q.pop(); ans++; } if (P < 0) ans = -1; break; } else { pre = p[i].x; if (P == 0) { q.push(p[i].sum); P = P + q.top(); q.pop(); ans++; } else if (P < 0) { while (P < 0 && (!q.empty())) { P = P + q.top(); q.pop(); ans++; } if (P < 0) { ans = -1; break; } else if (P == 0) { q.push(p[i].sum); P = P + q.top(); q.pop(); ans++; } else if (P>0) q.push(p[i].sum); } else q.push(p[i].sum); } } printf("%d ", ans); } return 0; }