POJ 2431-Expedition [优先队列] 《挑战程序设计竞赛》2.4

来源:互联网 发布:linux 关闭acl 编辑:程序博客网 时间:2024/05/21 09:42

题目链接

Description

A group of cows grabbed a truck and ventured on an expedition deep into the jungle. Being rather poor drivers, the cows unfortunately managed to run over a rock and puncture the truck’s fuel tank. The truck now leaks one unit of fuel every unit of distance it travels.

To repair the truck, the cows need to drive to the nearest town (no more than 1,000,000 units distant) down a long, winding road. On this road, between the town and the current location of the truck, there are N (1 <= N <= 10,000) fuel stops where the cows can stop to acquire additional fuel (1..100 units at each stop).

The jungle is a dangerous place for humans and is especially dangerous for cows. Therefore, the cows want to make the minimum possible number of stops for fuel on the way to the town. Fortunately, the capacity of the fuel tank on their truck is so large that there is effectively no limit to the amount of fuel it can hold. The truck is currently L units away from the town and has P units of fuel (1 <= P <= 1,000,000).

Determine the minimum number of stops needed to reach the town, or if the cows cannot reach the town at all.

Input

Line 1: A single integer, N

Lines 2..N+1: Each line contains two space-separated integers describing a fuel stop: The first integer is the distance from the town to the stop; the second is the amount of fuel available at that stop.

Line N+2: Two space-separated integers, L and P

Output

Line 1: A single integer giving the minimum number of fuel stops necessary to reach the town. If it is not possible to reach the town, output -1.

Sample Input

4
4 4
5 2
11 5
15 10
25 10

Sample Output

2

Hint

  • INPUT DETAILS:

The truck is 25 units away from the town; the truck has 10 units of fuel. Along the road, there are 4 fuel stops at distances 4, 5, 11, and 15 from the town (so these are initially at distances 21, 20, 14, and 10 from the truck). These fuel stops can supply up to 4, 2, 5, and 10 units of fuel, respectively.

  • OUTPUT DETAILS:

Drive 10 units, stop to acquire 10 more units of fuel, drive 4 more units, stop to acquire 5 more units of fuel, then drive to the town.

题目大意:

你需要驾驶一辆卡车行驶L单位距离.最开始时,卡车上有P单位的汽油.卡车每开1单位距离需要消耗1单位的汽油.如果在途中车上的汽油耗尽, 卡车就无法继续前行,因为无法到达重点.在途中一共有N个加油站.第i个加油站在距离终点 Ai 单位距离的地方, 最多可以给卡车加 Bi 单位汽油.假设卡车的燃料箱的容量时无限大的,无论加多少油都没有问题.那么请问卡车是否能到达终点?如果可以,最少需要加多少次油?如果可以到达终点,输出最少的加油次数,否则输出-1

题解:

觉得这题与POJ 1852 Ants有点像, 需要从整体的角度来看问题.
卡车在开往终点的途中,只有在加油站才可以加油.但是,如果认为”在到达加油站i时”就获得了一次在之后的任何时候都可以加 Bi 单位汽油的权利, 在解决问题上应该也是一样的.而在之后需要加由时,就认为是在之前经过的加油站加的油就可以了.
那么,因为希望到达终点时加油次数尽可能少,所以当燃料为0了之后再进行加油看上去是一个不错的方法.在燃料为0时,应该使用哪个加油站来加油呢?显然,应该选能加由 Bi 最大的加油站.
为了高效进行上述操作,我们可以使用从大到小的顺序一次取出数值的优先队列.

这题wa了我好多次, 找来测试数据才发现, 测试数据的并不是按照距离顺序的, 所以这题要先对输入数据进行排序. 测试数据附在下方链接

代码:

#include <iostream>#include <queue>#include <algorithm>#define MAX_N 10010using namespace std;int N, P, L;int pos = 0, ans = 0, tank = 0;typedef pair<int, int> Pair;Pair p[MAX_N];priority_queue<int> q;int main() {    cin >> N;    p[N].first = p[N].second = 0;    for (int i = 1; i <= N; i++)     cin >> p[i].first >> p[i].second;    sort(p+1, p+N+1);    cin >> L >> P;    pos = L; tank = P;    for (int i = N; i >= 0; i--) {    int d = pos - p[i].first;    while (d > tank) {        if (q.empty()) {        cout << -1 << endl;        return 0;        }        tank += q.top();        q.pop();        ans++;    }    tank -= d;    pos = p[i].first;    q.push(p[i].second);    }    cout << ans << endl;    return 0;}

测试数据

0 0