题目大意是,车子离城镇L单位长度,还有P升油,每开一个单位长度减1升,中途有n个加油站,每次能加一定数量的油,求最少加几次油能到目的地。油箱视为无限大。
或许你会想这样贪心:每次开车开到最远能行驶距离,在最后一个加油点加油,之后继续开,但是这个样例就把你卡死了。我们考虑这个题的关键所在就是,其实他不一定非要开到快没有油才加油,它要保证下一步油最多。
用mrclr大佬的话说,他其实可以开过了再回来加油(滑稽)
所以我们用一个堆来维护所走过的路程中,使你获得最多行走距离的加油站,每次把能走到的压到堆中,取堆顶即可。
看一下代码。
#include<cstdio> #include<algorithm> #include<cstring> #include<iostream> #include<cmath> #include<set> #include<queue> #define rep(i,a,n) for(int i = a;i <= n;i++) #define per(i,n,a) for(int i = n;i >= a;i--) #define enter putchar(' ') using namespace std; typedef long long ll; const int M = 200005; const int N = 1005; const int INF = 2147483647; int read() { int ans = 0,op = 1; char ch = getchar(); while(ch < '0' || ch > '9') { if(ch == '-') op = -1; ch = getchar(); } while(ch >= '0' && ch <= '9') { ans *= 10; ans += ch - '0'; ch = getchar(); } return ans * op; } struct node { int pos,val; bool operator < (const node &g) const { return val < g.val; } }a[M]; int T,n,l,p,g = 1,ans; priority_queue <node> q; bool flag = 0; bool cmp(node a,node b) { return a.pos < b.pos; } int main() { T = read(); while(T--) { n = read(); rep(i,1,n) a[i].pos = read(),a[i].val = read(); l = read(),p = read(); rep(i,1,n) a[i].pos = l - a[i].pos; sort(a+1,a+1+n,cmp); while(!q.empty()) q.pop(); ans = 0,flag = 0,g = 1; while(p < l) { while(a[g].pos <= p && g <= n) q.push(a[g++]); if(!q.empty()) p += q.top().val,ans++,q.pop(); else { printf("-1 "); flag = 1; break; } } if(!flag) printf("%d ",ans); } return 0; }