贪心加模拟。
先分两种情况:
1.从这个点加满油可以到达终点
a.从剩下的路程中找是否有价格更便宜的,如果有,就先到那个点(这里注意是一旦找到便宜的就立马结束本次寻找,先过去早说)。
b. 如果没有更便宜的,就直接到终点。
2.无法从这点到达终点
a.同上一种的a
b.判断下,是否这点能到的最大距离内是否有别的点,如果有则选一个价格最低的作为后继点;如果没有,则表明这次已经无法到达终点了,那么加满油,到达最大距离就结束整个模拟。
其中还需要注意的是汽油的存量,大部分时候,并不需要用到汽油的存量,因为如果能找到更便宜的后继点,我们并不需要加满油,只需要能到达后继点即可,因此这段路程中实际上相当于存量未变。但如果是要加满的情况下啊,就要先计算原来有多少,再进行下一步计算。
#include<iostream>
#include<cstdlib>
#include<cstdio>
#include<cmath>
#include<algorithm>
#include<cstring>
#include<climits>
using namespace std;
int c, final_dis, avg, n, max_cover;
struct Station{
float price, dis;
bool operator < (const Station &a) const {
return dis < a.dis;
}
}stations[505];
int main(){
scanf("%d%d%d%d",&c,&final_dis,&avg,&n);
max_cover = c * avg;
for(int i = 0; i < n; ++i){
scanf("%f %f",&stations[i].price,&stations[i].dis);
}
sort(stations,stations+n);
if(stations[0].dis != 0) {
printf("The maximum travel distance = 0.00");
return 0;
}
float cost = 0, pos = 0, tmp_price = stations[0].price, cap = 0;
int index = 0;
while(pos < final_dis){
float min_price = tmp_price;
int next_index = index;
if(pos + max_cover >= final_dis){//can arrive
for(int i = index; i < n; ++i){//find min price
if(stations[i].price < min_price){
min_price = stations[i].price;
next_index = i;
break;
}
}
if(min_price < tmp_price){//min price exist
cost += ((stations[next_index].dis - stations[index].dis)/avg-cap)*stations[index].price;
pos = stations[next_index].dis;
index = next_index;
tmp_price = min_price;
}
else{
cost += (final_dis - stations[index].dis)/avg*stations[index].price;
pos = final_dis;
}
}
else{//can not arrive
for(int i = index+1; i < n; ++i){//find min price
if(pos + max_cover < stations[i].dis) break;
if(stations[i].price <= min_price){
min_price = stations[i].price;
next_index = i;
break;
}
}
if(min_price <= tmp_price && index != next_index){//find a less price next
cost += (stations[next_index].dis - stations[index].dis)/avg*stations[index].price;
tmp_price = stations[next_index].price;
pos = stations[next_index].dis;
index = next_index;
}
else{
min_price = INT_MAX;
for(int i = index+1; i < n; ++i){//find min price
if(pos + max_cover < stations[i].dis) break;
if(stations[i].price < min_price){
min_price = stations[i].price;
next_index = i;
}
}
if(next_index == index){
pos += max_cover;
break;
}
else{
cost += (c*1.0-cap)*stations[index].price;
cap = c*1.0 - (stations[next_index].dis - stations[index].dis)/avg;
pos = stations[next_index].dis;
index = next_index;
}
}
}
}
if(pos == final_dis){
printf("%.2f",cost);
}
else
printf("The maximum travel distance = %.2f",pos);
return 0;
}