PAT1033 To Fill or Not to Fill (25)(贪心)
题意:
开车从起点出发,到终点的路上有一些加油站,不同的加油站油价不同,要求输出到终点时最少花费的钱
思路:
贪心,在加满油可以走的最大距离内分情况讨论:
- 在范围内存在加油站油价比当前加油站小,就加油加到刚好可以到那个加油站
- 在范围内不存在加油站油价比当前加油站小,说明当前加油站油价最小,所以在当前加油站加满油再走到不包括当前加油站的油价最小的加油站,也就是油价第二小的,此时会剩下一些油。
自己写的时候基本想到了上面的思路,但是对于第二张情况感觉不是很有把握,所以去写了dfs就搞得很难写,没写出来,这题还是有些难度。
#include<iostream>
#include<string>
#include<algorithm>
using namespace std;
const int INF = 0xfffff;
struct node {
double cost;
double distance;
}station[505];
int main() {
double cmax, d, davg;
int n;
cin >> cmax >> d >> davg >> n;
for (int i = 1; i <= n; i++) {
scanf("%lf%lf", &station[i].cost, &station[i].distance);
}
station[0] = { 0.0,d };
sort(station, station + n+1, [](const node &a, const node &b) {
return a.distance < b.distance;
});
double nowdis = 0.0, maxdis = 0.0, nowcost = 0.0, totalcost = 0.0;
double leftdis = 0.0; //剩下的油能走的公里数
if (station[0].distance != 0) {
printf("The maximum travel distance = 0.00");
return 0;
}
else {
nowcost = station[0].cost;
}
while (nowdis < d) {
maxdis = nowdis + cmax*davg;
double minCostDis = 0.0, minCost = INF;
bool flag = false;
//cout << nowdis << " " << totalcost << endl;
for (int i = 1; i <= n&&station[i].distance <= maxdis; i++) {
if (station[i].distance <= nowdis) continue;
if (station[i].cost < nowcost) {
totalcost += (station[i].distance - nowdis - leftdis) / davg*nowcost;
leftdis = 0.0;
nowcost = station[i].cost;
nowdis = station[i].distance;
flag = true;
break;
}
if (station[i].cost < minCost) {
minCost = station[i].cost;
minCostDis = station[i].distance;
}
}
if (flag == false && minCost != INF) {
totalcost += (nowcost*(cmax - leftdis / davg));
leftdis = cmax*davg - (minCostDis - nowdis);
nowcost = minCost;
nowdis = minCostDis;
}
if (flag==false&&minCost == INF) {
nowdis += cmax*davg;
printf("The maximum travel distance = %.2lf", nowdis);
return 0;
}
}
printf("%.2lf", totalcost);
return 0;
}