挑战编程 优先队列

  优先队列:维护队列中的最大值。

  题目大概是这样:长L的道路,n个加油站,加油站位置a[i],每个加油站可加油b[i],车子初始有油量P,求问车子是否可以走完路程 ,加油最少次数。车子油箱无限大。

 

  我们可以这样认为,车子不断走,一直走到没油的时候,需要加油了,这时候就可以从经过的所有加油站中选中一个可加油量最大的加油站,(因为加油次数尽量少,一次加油尽量多)这时候,我们用优先队列维护,车子所经过加油站的可加油的最大值。每次加油的时候,都从队列中得到队首元素,(也就是最大值)进行加油。

  代码:

  

#include <cstdio>
#include <iostream>
#include <queue>
#define maxn 10005
using namespace std;
int n,l,p;
int a[maxn],b[maxn];


int main()
{
    while (scanf ("%d %d %d",&n,&l,&p)!=EOF)
    {
        priority_queue<int>que;
        for(int i=0;i<n;i++){
             scanf ("%d %d",&a[i],&b[i]);
        }
        a[n]=n;
        b[n]=0;
        n++;//把终点位置也加如队列
        int pos=0,ans=0,tank=p;//pos是当前位置,tank是指当前车所有油量
        for(int i=0;i<n;i++)
        {
            int d=a[i]-pos;//下一步需要走的距离,等于下一个加油站到现在位置的距离
            while (tank-d<0)//如果当前油量不足以走d的话,说明需要加油
            {
                if(que.empty()==1)
                {
                    printf("-1\n");
                    return 0;
                }
                ans++;
                tank+=que.top();//加油,队首元素出队,。因为优先队列保存的是最大值,。
                que.pop();
            }
            tank-=d;
            pos=a[i];
            que.push(b[i]);//必须在此刻进行入队操作,不能先将所有油入队。因为车子是一步一步走的,到下一个 加油站的时候不能加油
        }
        printf("%d\n",ans);
    }
    return 0;
}  

  大概就是这样。。

posted on 2015-07-29 15:49  Bei_insomia  阅读(180)  评论(0编辑  收藏  举报

导航