链接
[http://poj.org/problem?id=2431]
题意
有个车开始有p升,n各加油站,总路程为l,给出每个站距离终点的距离以及可以加的油量,油箱容量无限,
问你最少加多少次可以到达终点。不可以到达输出-1;
分析
这题很巧妙的贪心用到了优先队列,而且细节处理很重要
先看看当前油是否可以到达下一站,如果不够就从前面经过的站选可以加的最大油量,一直到可以到达
下一站为止。用优先队列维护前面经过的站选可以加的最大油量
错误代码
因为没有考虑清楚到达终点的条件
具体看代码
#include<iostream>
#include<algorithm>
#include<queue>
using namespace std;
#define ll long long
struct str{
int dis,ca;
}a[10005];
int n,l,p;
bool cmp(str a,str b){
return a.dis<b.dis;
}
void solve(){
int ans=0,pos=0,tank=0;
priority_queue<int> que;
que.push(p);
for(int i=1;i<=n;i++){
int d=a[i].dis-pos;
while(tank-d<0){
if(que.empty()){
cout<<-1<<endl; return;
}
ans++; tank+=que.top(); que.pop();
}
tank-=d; que.push(a[i].ca); pos=a[i].dis;
}
cout<<ans-1<<endl;
}
int main(){
while(cin>>n){
for(int i=1;i<=n;i++)
cin>>a[i].dis>>a[i].ca;
cin>>l>>p;
for(int i=1;i<=n;i++) a[i].dis=l-a[i].dis;
a[0].ca=p,a[0].dis=0;//不知道自己为啥这么写
//起点不需考虑,因为刚开始的位置就是0,是没有用的
//这个代码就没有终点的位置所以错了,我迷茫了天,傻啊
sort(a,a+n+1,cmp);
//for(int i=0;i<=n;i++) cout<<a[i].dis<<' '<<a[i].ca<<endl;
solve();
}
return 0;
}
正确代码
#include<iostream>
#include<algorithm>
#include<queue>
using namespace std;
#define ll long long
struct str{
int dis,ca;
}a[10005];
int n,l,p;
bool cmp(str a,str b){
return a.dis<b.dis;
}
void solve(){
int ans=0,pos=0,tank=p;
priority_queue<int> que;
for(int i=1;i<=n;i++){
int d=a[i].dis-pos;
while(tank-d<0){
if(que.empty()){
cout<<-1<<endl; return;
}
ans++; tank+=que.top(); que.pop();
}
tank-=d; que.push(a[i].ca); pos=a[i].dis;
}
cout<<ans<<endl;
}
int main(){
//ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
//freopen("in.txt","r",stdin);
while(cin>>n){
for(int i=1;i<=n;i++)
cin>>a[i].dis>>a[i].ca;
cin>>l>>p;
for(int i=1;i<=n;i++) a[i].dis=l-a[i].dis;//反过来就是距离起点的距离
a[++n].ca=0,a[n].dis=l;//这个地方很关键,因为一定加入这个才能保证终点的位置存在
sort(a+1,a+n,cmp);
solve();
}
return 0;
}