有(N+1)个城市,0是起点N是终点,开车从0 -> 1 - > 2...... -> N,车每走1个单位距离消耗1个单位的汽油,油箱的容量是T。给出每个城市到下一个城市的距离D,以及当地的油价P,求走完整个旅途最少的花费。如果无法从起点到达终点输出-1。
例如D = {10, 9, 8}, P = {2, 1, 3},T = 15,最小花费为41,在0加上10个单位的汽油,在1加满15个单位的汽油,在2加2个单位的汽油,走到终点时恰好用完所有汽油,花费为10 * 2 + 15 * 1 + 2 * 3 = 41。
Input
第1行:2个数N, T中间用空格分隔,N + 1为城市的数量,T为油箱的容量(2 <= N <= 100000, 1 <= T <= 10^9)。 第2至N + 1行:每行2个数D[i], P[i],中间用空格分隔,分别表示到下一个城市的距离和当地的油价(1 <= D[i], P[i] <= 1000000)。
Output
输出走完整个旅程的最小花费,如果无法从起点到达终点输出-1。
Input示例
3 15 10 2 9 1 8 3
Output示例
41
这个题目一开始一点思路都没有,后来想每次到加油站都将油箱试图加满,如果里面的油都是比自己便宜的,不加。每次都替换油箱中比自己贵的油,然后跑完了一段再算之前的钱。即油先跑着,钱后算账。
把油箱里面的油按价钱分成相应的部分。每段路程车都是满油启动。
代码:
#pragma warning(disable:4996)
#include <iostream>
#include <algorithm>
#include <cmath>
#include <vector>
#include <string>
#include <cstring>
#include <set>
#include <queue>
#include <stack>
using namespace std;
typedef long long ll;
struct no
{
ll price;
ll num;
bool operator<(const no & n1)
{
return price < n1.price;
}
};
const int maxn = 100005;
ll n, t;
ll dis[maxn], pri[maxn];
void input()
{
int i, j, k;
scanf("%lld%lld", &n, &t);
for (i = 1; i <= n; i++)
{
scanf("%lld%lld", &dis[i], &pri[i - 1]);
}
}
void solve()
{
int i, j, k;
vector<no>qu;
int flag = 1;
ll res = 0;
for (i = 0; i <= n; i++)
{
if (t < dis[i + 1])flag = 0;
if (flag == 0)continue;
if (i == 0)
{
no n1;
n1.price = pri[0];
n1.num = t;
qu.push_back(n1);
}
else
{
sort(qu.begin(), qu.end());
ll di = 0;
ll rmin = 0;
while (true)
{
if (di + qu[0].num >= dis[i])
{
rmin = rmin + (dis[i] - di)*(qu[0].price);
if (di + qu[0].num >= dis[i])
{
qu[0].num = qu[0].num - (dis[i] - di);
}
if (qu[0].num == 0)
{
qu.erase(qu.begin());
}
break;
}
else
{
di = di + qu[0].num;
rmin += qu[0].num*qu[0].price;
qu.erase(qu.begin());
}
}
res += rmin;
ll sum = 0;
for (k = 0; k < qu.size(); k++)
{
if (pri[i] > qu[k].price)
{
sum += qu[k].num;
}
else
{
no n1;
n1.num = t - sum;
n1.price = pri[i];
qu.erase(qu.begin() + k, qu.end());
qu.push_back(n1);
sum = t;
break;
}
}
if (sum < t)
{
no n1;
n1.price = pri[i];
n1.num = t - sum;
qu.push_back(n1);
}
}
}
if (flag == 0)
{
puts("-1");
}
else
{
printf("%lld", res);
}
}
int main()
{
// freopen("i.txt","r",stdin);
// freopen("o.txt","w",stdout);
input();
solve();
return 0;
}