贪心算法,过程如下:
定义可达范围:从每一个加油站出发,能到达的最大距离;(即加满油时的情况)
所以我们在每一个加油站, 保证当前的油恰好可以到达 可达范围内第一个比当前油价便宜的加油站,
如果可达范围内都比当前油价贵,那就加满油(特例是终点在可达范围内,就不需要加满)。
思路还算清晰, 可代码写起来怎么那么纠结。。。有时间再去优化代码。
#include <iostream>
#include <cstdio>
#include <string>
#include <vector>
#include <algorithm>
using namespace std;
struct Node{
double price;
double location;
};
bool cmp(Node a, Node b)
{
return a.location < b.location;
}
vector<Node>v;
bool isEqual(double a, double b)
{
a -= b;
return a < 0.0000001 && a > -0.000001;
}
int main()
{
int cmax, d, davg, n, i, x;
scanf("%d %d %d %d", &cmax, &d, &davg, &n);
Node t;
for(i = 0; i < n; i ++)
{
scanf("%lf %lf", &t.price, &t.location);
v.push_back(t);
}
sort(v.begin(), v.end(), cmp);
if( !isEqual((*(v.end()-1)).location, d) )
{
t.location = d;
t.price = 0.0;
v.push_back(t);
n ++ ;
}
double can_reach = cmax * davg;
double cur_gas = 0.0;
double max_dis = 0.0;
double cur_location = 0.0;
double total_price = 0.0;
bool canReach = true;
for(i = 0; i < n; i ++)
{
if(cur_location + cur_gas * davg < v[i].location)
{
canReach = false;
max_dis = cur_location + cur_gas * davg;
break;
}
cur_gas -= (v[i].location - cur_location) / davg;
int chosen = i + 1;
bool has = false;
while(chosen < n && v[chosen].location <= v[i].location + can_reach)
{
if(v[chosen].price < v[i].price)
{
has = true;
break;
}
chosen ++ ;
}
if(has)
{
double need = (v[chosen].location - v[i].location) / davg;
if(need > cur_gas)
{
total_price += (need - cur_gas) * v[i].price;
cur_gas = need;
}
}
else
{
if(v[i].location + can_reach < d)
{
total_price += (cmax - cur_gas) * v[i].price;
cur_gas = cmax;
max_dis = v[i].location + can_reach;
}
else
{
double need = (d - v[i].location) / davg;
total_price += (need - cur_gas) * v[i].price;
cur_gas = need;
break;
}
}
cur_location = v[i].location;
}
if(canReach == false) printf("The maximum travel distance = %.2f\n", max_dis);
else printf("%.2f\n", total_price);
return 0;
}