接下來N行,每行兩個實數Di、Pi。
102.0 2.9
220.0 2.2
26.95
思路:是找在最大行駛距離內尋找比當前便宜的加油站,然後判斷是否能一次到達,不能的話先加滿,然後一個一個判斷直到剩下的油量不足到下一個加油站就加油,加適量。
於是有以下2 situations: 1.這個站點j 就是pos 再細分兩種情況: 1.從pos就可以走到終點 於是我們把油加到剛好到達終點即可 cost += ((d[i] - d[pos]) / d2 - remain)*p[pos];就得到了最後答案。 remain是當前剩餘的油 2.從pos不能一把走到終點 於是,從當前位置走,走到哪裏加油都不夠在pos這裏加油划算。 所以加滿。 2.這個站點j 是在pos後面的某個站點 也有兩種情況 1.當前剩餘的油remain不夠走到j 於是我們,把油加來剛好能夠走到j就行了。(因爲j這裏好好便宜!) 2.剩餘的油remain足夠,直接開過去就行了。
########具體操作見如下代碼
#include<iostream>
#include<algorithm>
#include<iomanip>
using namespace std;
double d[10000], p[10000]; //出發點每升汽油的價格p
int main()
{
ios::sync_with_stdio(false); //取消cin在stdin上的同步,增加cin的讀取效率
double d1, c, d2;
int n; //沿途油站數目
cin >> d1 >> c >> d2 >> p[0] >> n;
d[n + 1] = d1; //第n個油站後即爲最後的站點
for (int i = 1; i <= n; i++) //輸入每一個油站離出發點的距離以及每個站點汽油的價格
{
cin >> d[i] >> p[i];
}
int pos = 0;
double remain = 0, cost = 0;
do
{
bool found = false; //判定能不能到達
for (int i = pos + 1; i <= n + 1 && d[i] <= d[pos] + c*d2; i++) //循環判斷加滿油能不能到達下一個加油站
{
if (p[i] < p[pos]) //判斷下個站點汽油的價格是不是比這個pos站點汽油的價格小
{
if (d[pos] + remain*d2 >= d[i]) //若是剩餘的油足夠,剛好開過去
{
remain -= (d[i] - d[pos]) / d2; //剩餘的油減少,減少量就是從一個站點到下一個站點用到的油
}
else //剩餘的油不夠
{
cost += ((d[i] - d[pos]) / d2 - remain)*p[pos]; //還需要加的油花費的價錢,不用加滿
remain = 0; //到達下一個站點恰好沒油了,所以剩餘汽油量清0
}
pos = i;
found = true;
break;
}
}
if (!found)
{
cost += (c - remain)*p[pos]; //不能到達前花費了多少錢
remain = c - (d[pos + 1] - d[pos]) / d2; //還剩多少油
if (remain >= 0) pos++; //小於0,油根本不夠到達下一個站點,大於0,代表可以去下一個加油站
else
{
cout << "No Solution";
return 0;
}
}
} while (pos <= n); //循環條件:沒到達終點
cout.setf(ios::fixed); //以定點形式顯示浮點數
cout << setprecision(2) << cost;
}