题意:
一个人要从0位置开车到D位置,开始车里没有油,路上有一些加油站可以任意加油,但是油有不同的价格
问能不能到达D位置,能到达的话输出最小花费,不能到达输出最远到达距离
思路:
从开始位置加油,往后走,但是加多少油我们不确定,因为假如后面有一个加油站的油便宜,那我们到这个加油站加油,走后面的路程就会花费更小,前提是我们能到这样的加油站;
如果当前加油站加满能到达的后面的加油站油价都大于当前加油站,而我们又没到达终点,这时候只能从当前加油站把油加满;然后从能到达的加油站里面,油价最低的那个加油站把油箱补满。
然后再往后寻找合适的加油站,重复上述两个步骤;如果当前加油站加满油后到达不了下一个加油站,那么就无解,输出最远到达位置
#include<bits/stdc++.h>
#define FI first
#define SE second
using namespace std;
typedef pair<double,int> P;
const int maxn = 1000 + 7;
const double INF = 2e9 + 7;;
int c, d, m, n;
struct node {
int pos;
double p;
}a[maxn];
bool cmp(node a, node b) {
return a.pos < b.pos;
}
map<int,int> id;
void solve() {
sort(a+1,a+1+n, cmp);
for(int i = 1; i <= n+1; ++i) {
id[a[i].pos] = i;
}
if(a[1].pos != 0) {
printf("The maximum travel distance = 0.00\n");
return;
}
int lpos = 0;
double lp = a[1].p;
double mod = 0;
double ans = 0;
for(int i = 1; i <= n+1; i = id[lpos]) {
//cout << lp << " + " << lpos << " + " << ans << endl;
if(lpos >= d) {
printf("%.2f\n", ans);
return;
}
double minp = INF; int minpos = -1;
double nxp = INF, nxpos = -1;
bool ok = true;
for(int j = i+1; j <= n+1; ++j) {
if((a[j].pos-lpos) > c*m) break;
if(ok && (a[j].p < lp)) {
nxp = a[j].p;
nxpos = a[j].pos;
ok = false;
}
if(a[j].p < minp) {
minp = a[j].p;
minpos = a[j].pos;
}
}
if(minpos == -1) {
lpos += c*m;
printf("The maximum travel distance = %.2f", (double)lpos);
return;
}
if(!ok) {
minp = nxp;
minpos = nxpos;
}
if(minp < lp) {
ans += (lp * ((minpos-lpos) / (1.0*m) - mod));
mod = 0;
lp = minp;
lpos = minpos;
}
else {
ans += (lp * (c - mod));
mod = (1.0*c - (minpos-lpos) / (1.0*m));
lp = minp;
lpos = minpos;
}
}
}
int main() {
scanf("%d%d%d%d", &c, &d, &m, &n);
for(int i = 1; i <= n; ++i) {
scanf("%lf%d", &a[i].p, &a[i].pos);
}
a[n+1].pos = d;
a[n+1].p = 0;
solve();
return 0;
}