原題連結:https://www.luogu.com.cn/problem/P1016
題意解讀:用最少的加油費用到達另一個城市,中間有若干加油點,起點也可加油。
解題思路:
本題是一個貪心策略題:
列舉每一個加油點i:
1、初始加油點是起點
2、汽車能跑的最大距離範圍內,找到下一個更便宜的加油點的位置
3、如果能找到更便宜的加油點j,則在i點加的油只需滿足能跑到j點即可
4、如果在最大距離範圍內找不到更便宜的加油點
看看從i點能否直接跑到終點,如果可以在i點加的油滿足能跑到終點即可
如果從i點無法跑到終點,則在i點加滿油,並在最大距離範圍內找價錢最便宜的加油點j
加油點i設定為j,繼續列舉。。。
100分程式碼:
#include <bits/stdc++.h>
using namespace std;
double d1; //兩個城市距離
double c; //郵箱容量(升)
double d2; //每升汽油行使距離
double p; //起點油價
int n; //加油站數量
double dist[10]; //每個加油點距離起點的距離,包括起點和終點,起點是0,終點是d1
double price[10]; //每個加油點的油價,起點是p,終點是1e9
double ans;
int main()
{
scanf("%lf%lf%lf%lf%d", &d1, &c, &d2, &p, &n);
dist[1] = 0, price[1] = p;
for(int i = 1; i <= n; i++)
{
scanf("%lf%lf", &dist[i + 1], &price[i + 1]);
}
dist[n + 2] = d1, price[n + 2] = 1e9;
double maxdist = c * d2; //maxdist表示加滿油最多行使的距離
double rest = 0; //郵箱剩餘油量
for(int i = 2; i <= n + 2; i++)
{
if(dist[i] - dist[i - 1] > maxdist) //如果兩點之間距離超過加滿油可行駛最大距離,則無解
{
cout << "No Solution";
return 0;
}
}
int i = 1; //i列舉每個加油點,從起點開始
while(i <= n + 1)
{
//在可以行使的最大距離內,找到第一個比i點便宜的加油點
bool yes = false;
int j;
for(j = i + 1; j <= n + 1 && dist[j] - dist[i] <= maxdist; j++)
{
if(price[j] < price[i])
{
yes = true;
break;
}
}
if(yes) //有找到便宜的加油點
{
ans += ((dist[j] - dist[i]) / d2 - rest) * price[i]; //在i點加油能跑到j點即可
rest = 0; //到j點後剩下的油量
}
else //沒有找到便宜的加油點
{
if(dist[n + 2] - dist[i] <= maxdist) //沒有更便宜的加油點,但可以跑到終點
{
ans += ((dist[n + 2] - dist[i]) / d2 - rest) * price[i]; //直接加油夠跑到終點
break; //結束
}
else //不能跑到終點
{
ans += (c - rest) * price[i]; //則在i點把郵箱加滿
double minp = 2e9, mini = i;
//找到i之後j之前價格最低的點
for(int k = i + 1; k < j; k++)
{
if(price[k] < minp)
{
minp = price[k];
mini = k;
}
}
j = mini; //下次從價格最低的點加油
rest = c - (dist[j] - dist[i]) / d2; //到j點後剩下的油量
}
}
i = j; //下一個加油點是j
}
printf("%.2lf", ans);
return 0;
}