加油站

加油站

题目描述

奶牛们开车到郊外旅游,由于驾驶技术不行,不小心撞到了石头,油箱漏油了。现在汽车每走一单位距离,油箱就损耗和漏掉共一单位油。
为了修车,必须把车开到最近的小镇(不会超过10,000,000单位距离),到小镇的路可以认为是在一条直线上。从现在的位置到小镇途中, 共有 N (1 <= N<=50,000) 个加油点,第i个加油点位于距离小镇有D_i (1 <= D_i< L)单位距离的地方,该加油站储油F_i (1 <= F_i<= 100)单位.由于路途艰险,奶牛们想尽量把加油的次数减到最少.汽车的油箱可以认为是无穷大. 汽车现在为于距离小镇L个单位距离的地方,并且有P单位的油(1 <= P <=10,000,000).请你计算最少要加多少次油才能到达小镇,或者汽车根本开不到小镇. 注意:在同一地点,可能有多个加油站,但是,在计算时,它们是独立的,认为是两个不同的加油站。

输入格式 1854.in

* 1: 三个整数: N LP.
*
2..N+1: 两个整数: D_i F_i. 对应着一个加油站。

输出格式 1854.out

* 一行: 到达小镇需要的最少的加油次数,如果无法到达小镇, 输出-1.

输入样例 1854.in

4 25 10
4 4
5 2
11 5
15 10

输出样例 1854.out

2


【输入解释】
汽车现在在距离小镇25个单位距离的地方,汽车有10个单位的汽油. 
在途中, 4 个加油站,他们分别位于距离小镇: 4 5 1115个单位距离的地方。(可以看出,它们跟汽车现在位置的距离分别是:212014104个加油站的储油量分别是: 4 2 510

【输出解释】
汽车开10单位距离后, 停车加10单位的油, 再开4单位距离,停车加5单位的油, 然后就可以开到小镇了。

     这题用到了贪心+优先队列。

思路分析:

    当车遇到加油站的时候,就直接加油,一定好吗?答案是否定的,当开到某一个加油站的时候,花一次加油的机会,加到的油还不一定多,而后面同样能到达的加油站,说不定能加更多的油。

    因此贪心的策略就是,尽量走到能走的地方,取一个加油量最大的加油。

具体实现:

    当走到某段路的时候,便看看从now能不能走到这个位置(油量够不够)

    如果不够,就要加油,可是如果在之间的这一段路都没有一个加油站,那么优先队列q会为空,无解。

    否则就在加油最多的地方加油,也就是优先队列的top,把这些油加进来以后,再把这个加油站删掉。

    进行上述重复操作,直到油量,可以到达此时的地方。

#include
   
   
    
    
#include
    
    
     
     
#include
     
     
      
      
#include
      
      
       
        
using namespace std;
const int maxn=50005;
int n,l,p,b,ans=0,f;

priority_queue
       
       
         q; struct you { int far,va; }a[maxn]; bool cmp(you x,you y) { if(x.far==y.far) return x.va>y.va; return x.far 
        
          >n>>l>>p; for(int i=1;i<=n;i++) { cin>>b>>f; a[i].far=l-b; a[i].va=f; } sort(a+1,a+1+n,cmp); int head=1,tail=0,now=0,v=0;//now为现在在哪 a[n+1].far=l; for(int i=1;i<=n+1;i++) { while(a[i].far-now>p)//p为油 { if(q.empty()) { v=1; break; } p+=q.top(); q.pop(); ans++; } if(v==1) break; p-=(a[i].far-now); now=a[i].far; q.push(a[i].va);//注意这里不要存错参数啦!!! } if(v==1) cout<<-1< 
          
         
       
      
      
     
     
    
    
   
   

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值