其实题目本身不难,难就难在对贪心策略的选取
在每一个加油点应该做这样的判断:
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; }
PAT 1033. To Fill or Not to Fill (25)(贪心),布布扣,bubuko.com
PAT 1033. To Fill or Not to Fill (25)(贪心)
原文地址:http://blog.csdn.net/youmengjiuzhuiba/article/details/38665925