很坑的一道贪心题
策略是:
如果范围内有离他最近比它便宜的,就只加油到能够达到那个点的量。
如果没有,就加满,然后到它范围内最便宜的点。
注意:有很多特判
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;
#define ll long long
const ll inf=0x3f3f3f3f;
#define read(x) scanf("%lld",&x)
struct node
{
double pric;
double dis;
bool operator < (const node& x)const
{
return dis<x.dis;
}
}a[1005];
int main()
{
double C,D,avg;
cin>>C>>D>>avg;
ll N;
cin>>N;
for(int i=0;i<N;i++)
{
scanf("%lf %lf",&a[i].pric,&a[i].dis);
}
sort(a,a+N);
double lef=0.0;
ll pos=0;
double maxlen=C*avg;
double ans=0;
if (a[0].dis!=0)
{
double tt=0;
cout << "The maximum travel distance = ";
printf("%.2lf\n",tt);
return 0;
}
while (true) {
double pp=0;
ll nxtpos = -1;
for (int i = pos + 1; (i < N) && (a[i].dis - a[pos].dis <= maxlen); i++) {
if (a[i].pric <= a[pos].pric)//!!!!!!!!!!!
{
nxtpos = i;
break;
}
}
if (nxtpos == -1) {
if (a[pos].dis + maxlen >= D) {
double needgas = (D - a[pos].dis) / avg;
if (lef >= needgas) {
printf("%.2lf\n",ans);
// cout << ans << '\n';
return 0;
} else {
printf("%.2lf\n",ans + (needgas - lef) * a[pos].pric);
// cout << ans + (needgas - lef) * a[pos].pric;
return 0;
}
}
double minnprc = 10000000.0;
for (int i = pos + 1; (i < N) && (a[i].dis - a[pos].dis <= maxlen); i++) {
if (a[i].pric < minnprc) {
minnprc = a[i].pric;
nxtpos = i;
}
}
if (nxtpos == -1) {
cout << "The maximum travel distance = ";
printf("%.2lf\n",a[pos].dis + maxlen);
return 0;
}
ans += (C - lef) * a[pos].pric;
pp+=(C - lef) * a[pos].pric;
lef = C;
lef-=(a[nxtpos].dis-a[pos].dis)/avg;
} else {
double needgas = (a[nxtpos].dis - a[pos].dis) / avg;
// if (pos==6)cout<<needgas<<"!"<<'\n';
if (lef >= needgas) {
lef = lef - needgas;
} else {
ans += (needgas - lef) * a[pos].pric;
// if (pos==6)cout<<(needgas - lef)<<"!\n";
pp+=(needgas - lef) * a[pos].pric;
lef = 0;
}
}
// cout<<pos<<' '<<nxtpos<<' '<<a[nxtpos].dis-a[pos].dis<<' '<<pp<<' '<<lef<<'\n';
pos = nxtpos;
}
}