解题思路:
其实题目本身不难,难就难在对贪心策略的选取
在每一个加油点应该做这样的判断:
1、首先计算从本加油点做多可能达到的加油点
2、如果有可达加油点的话:
2.1 寻找有无比当前加油点油价便宜的加油点,如果有的话就跑到该便宜的加油点,油量加到支持到该加油点即可
2.2 如果没有比当前加油点更便宜的加油点的话,又分两种情况:
2.2.1、如果本次加油可能直接到终点,就加可以到达终点的油量
2.2.2、否则的话,加满
3、如果没有可达加油点的话:
3.1 看是否可以直接达到终点
3.2 不能达到终点计算最大抵达路程
warning:这里可能没有第0号加油站哦
代码如下:
#include<iostream>
#include<fstream>
#include<vector>
#include<algorithm>
#include<stdio.h>
using namespace std;
struct station{
double distance;
double price;
};
vector<station>stations;//加油站信息
double minPrice = 99999999;// 最小的价格
double maxArrived = 0;//最大能够抵达的距离
int cmax,d,davg,n;
bool cmp(const station &s1 ,const station &s2){
if(s1.distance>s2.distance)return false ;
else return true;
}
/**
@parm currTotalPrice //当前消费
@parm curr 当前位置
@parm gas 当前剩余油量
*/
void find_next_station(double currTotalPrice,int curr,double gasLength,double max_len){
vector<int>sindex;
double currLen = (stations[curr]).distance;
int currIndex = curr;
double cheapPrice =9999999;
int cheapIndex=0;
bool flag = false;
for(int i=curr+1;i<stations.size();++i){
if(!flag&&stations[i].distance-currLen <= max_len ){
sindex.push_back(i);
if(stations[i].price<stations[curr].price){
cheapPrice = stations[i].price;
cheapIndex = i;
flag=true;
}
}
}
if(sindex.size()>0){
if(cheapPrice<stations[curr].price){//下一个最便宜的比当前的便宜
double pushGasLen = stations[cheapIndex].distance - stations[curr].distance-gasLength;
currTotalPrice+=stations[curr].price * pushGasLen*1.0/(davg*1.0) ;
gasLength+= pushGasLen;
}else{
//下一个加油站没有比当前便宜的了
/**
如果本次可以加油到终点,那就直接加到终点的油量
否则的话直接加满
*/
if(stations[curr].distance+max_len>=d){
double pushGasLen = d - stations[curr].distance -gasLength;
currTotalPrice += stations[curr].price * pushGasLen*1.0/(davg*1.0);
if(currTotalPrice < minPrice){
minPrice=currTotalPrice;
}
maxArrived = d;
return ;
}else{
double pushGasLen = max_len - gasLength;
currTotalPrice+=stations[curr].price * pushGasLen*1.0/(1.0*davg);
gasLength = max_len;
}
}
if(cheapIndex!=0)
curr = cheapIndex;
else
curr = sindex.at(sindex.size()-1);
gasLength -= stations[curr].distance-stations[currIndex].distance;
find_next_station(currTotalPrice,curr,gasLength,max_len);
}else{
/**
即使加满了也不能或者没有下一个加油站了
1、直接抵达终点
2、永远抵达不了终点了
*/
if(stations[curr].distance+max_len>=d){//可达
double lastDistance = d-stations[curr].distance;
currTotalPrice =currTotalPrice+ (lastDistance*1.0/davg)*stations[curr].price;
if(currTotalPrice<minPrice)
minPrice = currTotalPrice;
maxArrived = d;
// cout<<"minPrice "<<minPrice<<endl;
}else{//不可达
double distance = stations[curr].distance+max_len;
if(distance>maxArrived){
maxArrived = distance;
}
}
return ;
}
}
int main(){
ifstream cin("data.txt");
cin>>cmax>>d>>davg>>n;
const double MAX_LEN=cmax*davg;
bool noway =true;
for(int i=0;i<n;++i){
station s;
cin>>s.price>>s.distance;
stations.push_back(s);
if(s.distance==0){
noway=false;
}
}
if(noway)//没有第0个加油站,汽车启动不了啊
{
printf("The maximum travel distance = %.2lf\n",maxArrived);
return 0;
}
sort(stations.begin(),stations.end(),cmp);
find_next_station(0,0,0,MAX_LEN);
if(maxArrived<d){
printf("The maximum travel distance = %.2lf\n",maxArrived);
}else{
printf("%.2lf\n",minPrice);
}
return 0;
}