zoukankan      html  css  js  c++  java
  • 优先队列的使用——Expedition

    一、题目描述

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

    二、问题分析

    由于加油站的数量非常大,必须像一个高效的解法。

    在卡车开往终点的途中,只有在加油站才可以加油。我们换一种思考方式,如果认为“在到达加油站时i时,再次之后的任何时候都获得了加Bi油的权利”。因为希望到达终点的加油次数尽可能地少,我们可以加经过地加油站的加油量放入优先队列,当油量不足以到达下一站,则取出优先队列中的最大值,其实就是贪心算法,取所有权力中的最大值,最坏的情况时,每次油量都不够,需要从队列中取,此时时间复杂度O(nlogn).

    三、代码实现

     1 #include<stdio.h>
     2 #include<iostream>
     3 #include<queue>
     4 #include<algorithm>
     5 #include<cstring>
     6 using namespace std;
     7 
     8 const int maxn = 10000 + 10;
     9 struct Station
    10 {
    11     int pos;
    12     int fuel;
    13     bool operator < (const Station &n)const {
    14         return (pos < n.pos);
    15     }
    16 }sta[maxn];
    17 int n, L, P;
    18 
    19 void slove()
    20 {
    21     //把终点也认为是一个加油站,写起来更加方便
    22     sta[n].pos = L;
    23     sta[n].fuel= 0;
    24     n++;
    25 
    26     priority_queue<int>que;
    27     int ans = 0,pos = 0, tank = P; //pos表示当前位置,tank表示当前油量
    28 
    29     sort(sta, sta + n);            //使各加油站的位置从小到大排列
    30 
    31     for (int i = 0; i < n; i++)
    32     {
    33         int d = sta[i].pos - pos;
    34 
    35         //油量不够则加油
    36         while (tank - d < 0)
    37         {
    38             if (que.empty())
    39             {
    40                 printf("-1
    ");
    41                 return;
    42             }
    43             tank += que.top();
    44             que.pop();
    45             ans++;
    46         }
    47         tank -= d;
    48         pos = sta[i].pos;
    49         que.push(sta[i].fuel);
    50     }
    51     printf("%d
    ", ans);
    52 }
    53 int main()
    54 {
    55     scanf("%d", &n);
    56     for (int i = 0; i < n; i++)
    57         scanf("%d%d", &sta[i].pos, &sta[i].fuel);
    58     scanf("%d%d", &L, &P);
    59     for (int i = 0; i < n; i++)
    60         sta[i].pos = L - sta[i].pos;
    61     
    62     slove();
    63     return 0;
    64 }

    四、总结

    熟练应用优先队列能很好的解决许多问题。

  • 相关阅读:
    一张一驰,文武之道
    关于“未能加载……”和“web.config”
    DotText学习心得_1
    windows服务与事务
    AWR报告生成
    Java EE启示录
    跨入安全的殿堂读《Web入侵安全测试与对策》感悟
    用VS2005写Loadrunner测试脚本
    List of Free Programming books
    硬盘基础知多少
  • 原文地址:https://www.cnblogs.com/lfri/p/9457689.html
Copyright © 2011-2022 走看看