贪心,优先队列
题目链接:http://poj.org/problem?id=2431
题目大意:
一辆卡车,初始时,距离终点L,油量为P,在起点到终点途中有n个加油站,每个加油站油量有限,而卡车的油箱容量无限,卡车在行车途中,每走一个单位的距离消耗一个单位的油量,给定n个加油站距离终点的距离以及油存储量。问卡车是否能到达终点,如果可达,最少需要加多少次油,否则输出-1.
题目思路:
采用贪心的思想,卡车当然在不加油的情况下走的越远越好了,而当它没油时,我们再判断卡车在经过的途中的加油站,哪个加油站加的油最多,选油量最多的,这样后面加油次数也越少,然后又继续行驶,当它又没油了的时候,继续选它从起点到该点所经过的加油站油量最多的加油。
做法先将加油站到终点的距离由远到近排下序,这样离起点就是由近到远。就是每经过一个加油站就将该加油站的油量压入优先队列中,然后每次没油的时候,去队首元素加油即可。
参考:https://www.cnblogs.com/zjl192628928/p/9414201.html
为什么这样做呢,经过加油站后还可以加油?其实不是这样的,只是预先模拟汽车到达那个加油站的情况,并不是汽车真正到达那个加油站,这样才能预算沿途究竟在哪个加油站加油最好。之前纠结这个有点久2333,后来就想想这个只是预想汽车到达那个加油站,并没有真正到达
Code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71
|
#include <iostream> #include <queue> #include <algorithm> using namespace std;
const int MAXN = 1E6;
struct node { int x, y; }stru[MAXN];
bool cmp(node x1, node x2) { return x1.x < x2.x; }
int main() { ios::sync_with_stdio(false); int p, l, n; cin >> n; for(int i = 0; i < n; i++) cin >> stru[i].x >> stru[i].y; cin >> p >> l;
for(int i = 0; i < n; i++) stru[i].x = p - stru[i].x;
stru[n].x = p; stru[n].y = 0; n++; sort(stru, stru + n, cmp);
priority_queue<int>pq; int ans = 0, pos = 0, tank = l;
for(int i = 0; i < n; i++) { int d = stru[i].x - pos; while(tank - d < 0) { if(pq.empty()) { puts("-1"); return 0; } tank += pq.top(); pq.pop(); ans++; }
tank -= d; pos = stru[i].x; pq.push(stru[i].y); } cout << ans; return 0; }
|