POJ2431

来源:互联网 发布:神机妙算软件升级 编辑:程序博客网 时间:2024/05/22 10:54

生命不息,奋斗不止!

@author stormma
@date 2017/10/20

题意:一辆卡车距离城镇L单位长度,初始有P油,每行驶一个单位长度消耗一单位油。有n个加油站可以加油,给出n个加油站与城镇的距离Ai,和在加油站可以加的有的量Bi,问最少加油几次才能行驶L长度,如果不能输出-1。
我们稍微变换一下思路:每次经过加油站,都把油装到瓶子里面带走,Bi加入优先队列,到需要加油的时候才加,因为需要使加油的次数最少,每次都是选油量最大的加。如果优先队列为空而没有到达下一加油站或是终点。则不能够到达。

思路分析
换个思路想,我们判断从加油站A到B,如果不能到,我们加之前最大油量的加油站的油,那么问题来了,我们怎么维护前面加油站的油量呢?可以用优先队列,判断不能到B,就取出队加油,如果还不能到,继续加,这样保持加的都是最大加油站的油,直到队列为空,还不到就输出-1即可。

实现代码

package me.stormma.poj;import java.util.*;/** * 加油站问题 <a href="">题目链接</a> * * @author stormma * @date 2017/10/19 */public class Main2431 {    private static int solve(List<Stop> stops, int L, int P) {        PriorityQueue<Integer> queue = new PriorityQueue<>(new Comparator<Integer>() {            @Override            public int compare(Integer o1, Integer o2) {                return o2.compareTo(o1);            }        });        // ans加油次数,pos当前距起点位置,tank当前        int ans = 0, pos = 0, tank = P;        for (Stop stop : stops) {            // 到下一个加油站的距离            int dis = stop.dis - pos;            // 如果到不了,加油            while (tank < dis) {                if (queue.isEmpty()) {                    return -1;                }                // 加经过的加油站最大加油量的                tank += queue.poll();                ans++;            }            tank -= dis;            // 更新当前位置            pos = stop.dis;            // 向优先队列中增加这个加油站的油量            queue.add(stop.tank);        }        return ans;    }    public static void main(String[] args) {        Scanner in = new Scanner(System.in);        // 加油站数量        int N = in.nextInt();        // 距离终点的距离        List<Stop> stops = new ArrayList<>();        for (int i = 0; i < N; i++) {            stops.add(new Stop(in.nextInt(), in.nextInt()));        }        // 起点到终点的距离        int L = in.nextInt();        // 起始油量数        int P = in.nextInt();        for (Stop stop: stops) {            stop.dis = L - stop.dis;        }        // 终点当做加油站        stops.add(new Stop(L, 0));        Collections.sort(stops, (o1, o2) -> o1.dis - o2.dis);        System.out.println(solve(stops, L, P));    }    static class Stop {        /**加油站距离起始位置的距离*/        int dis;        /**加油站一次可以加的油*/        int tank;        public Stop(int dis, int tank) {            this.dis = dis;            this.tank = tank;        }    }}