Expedition

(POJ 2431)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. 

GOAl:  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.

INPUT:  4 (代表4 fuel stops)

             15 10 (第一个数字代表该加油站距离town的距离, 第二个数字代表该加油站能够加的油, 下面三行同此)

             11  5

             5  2

             4 4

             25 10  (第一个表示路线总的长度为25, 第二个是卡车在起点处具有的油量)

OUTPUT: 

             2 

刚开始, 卡车由P单位的汽油。 卡车没开1单位的距离需要耗掉1单位的汽油。  目的是求出最少要在几个加油站停下来加油, 才能到达L处的目的地

分析: 该题的解决用到了优先队列的知识。  由于所有的加油站都在一条直线上, 所以总会经过每个加油站, 只要看需不需要停下来加油。 所以我们尽可能的往前走, 把中途经过的加油站的能够加的油量放在一个priority queue里面, 然后直到中途没有油了, 我们就决定从priority queue中最大的油量加到tank,  因为既然要加油, 就加到最大的油。 这隐含的意思就是我们会在这一站停下来加油。 

程序:

#include <cstdio>
#include <algorithm>
#include <queue>

using namespace std;

struct fuel_stop{
    int pos;
    int amount;
}stop[10010];

bool cmp(fuel_stop a, fuel_stop b)
{
    return a.pos > b.pos;
}

int main()
{
    int N, L, P;
    while (scanf("%d", &N) != EOF) {
        for (int i = 0; i < N; ++i)
            scanf("%d %d", &stop[i].pos, &stop[i].amount);
        scanf("%d %d", &L, &P);

        sort(stop, stop + N, cmp);

        stop[N] = {0,0};  // 终点也是一个stop
        priority_queue<int> PQ;  // PQ存放经过的每一个stop的油量

        int dis = L - stop[0].pos;  // 起点距离第一站
        int sum_dis = dis;          // 总共走了多远
        P -= dis;

        int i = 0;
        int ans = 0;
        bool OK = 1;
        while (sum_dis < L && OK) {
            while (P >= 0) {   //當身上油還>=0時繼續前進
                dis = stop[i].pos - stop[i+1].pos;
                P -= dis;
                sum_dis += dis;
                PQ.push(stop[i].amount);
                ++i;
                if (i == N) break;
            }
            while (P < 0 && OK) {  // PQ裡面從最多油量開始挑,加入油箱
                if (PQ.empty()) OK = 0;
                else{
                    P += PQ.top();
                    PQ.pop();
                    ++ans; // 加一次油
                }
            }
        }
        if (OK) printf("%d\n", ans);
        else puts("-1");
    }
}

运行结果如下:


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值