您的位置:首页 > 其它

汽油补给

2017-11-30 02:42 155 查看
有(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
#include <iostream>
#include <algorithm>
using namespace std;

typedef long long int ll;
const int MAXN = 1e5 + 10;
const int MAXP = 1e6 + 10;
ll D[MAXN];
ll P[MAXN];
ll leftP[MAXN];
ll leftD[MAXN];
ll N, T;

int main(int argc, const char * argv[])
{
cin >> N >> T;
for (ll i = 1; i <= N; i++)
{
cin >> D[i] >> P[i];
if (D[i] > T)
{
cout << "-1" << endl;
return 0;
}
}
D[N+1] = 0;
P[N+1] = MAXP;
ll result = 0;
ll pos = -1;
ll posLeft = -1;
ll sumLeft = 0;
ll buf[MAXN];

for (ll i = 1; i <= N + 1; i++)
{
if ((pos == -1) || (P[i] <= P[buf[pos]]))
{
pos++;
buf[pos] = i;
}
else
{
for (ll j = 0; j <= pos; j++)
{
while ((posLeft >= 0) && (P[buf[j]] < leftP[posLeft]))
{
result -= (leftP[posLeft] * leftD[posLeft]);
sumLeft -= leftD[posLeft];
posLeft--;
}

ll temp = D[buf[j]];

if (temp > sumLeft)
{
result += (temp - sumLeft) * P[buf[j]];
sumLeft = 0;
posLeft = -1;
}
else
{
ll index = 0;
while (temp > 0)
{
if (temp < leftD[index])
{
sumLeft -= temp;
leftD[index] -= temp;
temp = 0;
}
else
{
sumLeft -= leftD[index];
temp -= leftD[index];
leftD[index] = 0;
index++;
}
}
}
}
posLeft++;
leftP[posLeft] = P[buf[pos]];
leftD[posLeft] = T - D[buf[pos]] - sumLeft;
result += (leftD[posLeft] * P[buf[pos]]);
sumLeft = T - D[buf[pos]];

pos = 0;
buf[pos] = i;
}
}

while (posLeft >= 0)
{
result -= (leftP[posLeft] * leftD[posLeft]);
posLeft--;
}

cout << result << endl;

return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: