题目大意:用卡车将一群牛穿过丛林送到一个小镇上,途中有N个加油站,每个加油站的距离和油量确定,卡车的邮箱容量无限,总距离为L,初始油量为P,求途中最少加油的次数,若无法到达则输出-1.注意:每经过一个单位的距离消耗一个单位的油量。
思路:可以想象一下,每次经过一个加油站Ai的时候,就相当于获得了一次在任意时刻加Bi油量的机会。则每当油箱中油量为0的时候,可以加所经过的最大的Bi,则加油的次数自然最小。
步骤:
1.priority_quequ优先序列,每当经过加油站Ai的时候,将Bi放入quequ队列。
2.所给出的距离均为加油站离小镇的距离,故可以转化成加油站到出发点的距离,并从小到大排列。
3.每到一个加油点之前,先判断是否能够到此加油点,不能的话,则在队列中找到最大的加油量,队列为空的话则输出-1;若不为空,则加一次油,油量为队列中的最大值。再将当前位置,油量,队列等数据更新。
代码如下:
#include<iostream>
#include<queue>
#include<algorithm>
using namespace std;
struct node
{
int len,cp;
}a[10000+10];
bool comp(node a,node b)
{
return a.len>b.len;
}
int main()
{
priority_queue<int> que;
int N,L,P,i;
while(cin>>N)
{
for(i=0;i<N;i++)
cin>>a[i].len>>a[i].cp;
sort(a,a+N,comp);
cin>>L>>P;//L为总距离,P为刚开始邮箱中的油量
for(i=0;i<N;i++)
a[i].len=L-a[i].len;
a[N].len=L;
a[N].cp=0;
int pos=0,cap=P,dis,count=0;//pos为当前位置,cap为油箱容量,dis为到下一加油点的距离,count为加油次数
for(i=0;i<=N;i++)
{
dis=a[i].len-pos;
while(cap<dis)
{
if(que.empty())
{
count=-1;
break;
}
cap+=que.top();
que.pop();
count++;
}
if(count==-1)break;
cap-=dis;
pos=a[i].len;
que.push(a[i].cp);
}
cout<<count<<endl;
}
return 0;
}