题解 P1016 【旅行家的预算】
这道题贪心就好了:
如所有经过的加油站中,多加最便宜的油一定是坠吼的;
这样一来将所有经过的加油站的最大加油量(就是C)和油价加到优先队列里,只要走着走着没油了,就从优先队列取出最便宜的油,加至恰好能到达下一个加油站(因为也许那里的油比你已经经过的更便宜),然后将它的最大加油量减去你加了的部分重新加入队列,如果堆顶的不够加,就继续取第二小,第三小的,如果所有能加的油都加完了还不能到达目的地,就无解。
代码如下,不太好看,勿喷^_^
#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
using namespace std;
struct oil{
double rest,cost;
bool operator < (const oil& rhs) const{
return cost>rhs.cost;
}
};
priority_queue<oil> Q;
double dis[105],cost[105],D1,D2,P,C;
int N;
int main(){
cin>>D1>>C>>D2>>P>>N;
dis[0]=0;
for(int i=1;i<=N;i++){
cin>>dis[i]>>cost[i];
}
dis[N+1]=D1;
N++;
for(int i=N;i>=1;i--) dis[i]-=dis[i-1];
int k=1;
double ans=0;
Q.push((oil){C,P});
while(k<=N){
double to=dis[k];
while(to>0){
if(Q.empty()){
cout<<"No Solution";
return 0;
}
oil o=Q.top();
Q.pop();
if(o.rest*D2>=to){
o.rest-=to/D2;
ans+=to/D2*o.cost;
to=0;
if(o.rest>0) Q.push((oil){o.rest,o.cost});
}else{
to-=o.rest*D2;
ans+=o.rest*o.cost;
}
}
Q.push((oil){C,cost[k]});
k++;
}
printf("%.2f",ans);
}