有(N+1)个城市,0是起点N是终点,开车从0 -> 1 - > 2...... -> N,车每走1个单位距离消耗1个单位的汽油,油箱的容量是T。给出每个城市到下一个城市的距离D,以及当地的油价P,求走完整个旅途最少的花费。如果无法从起点到达终点输出-1。
第2至N + 1行:每行2个数D ii, P ii,中间用空格分隔,分别表示到下一个城市的距离和当地的油价(1 <= D ii, P ii <= 1000000)。 Output输出走完整个旅程的最小花费,如果无法从起点到达终点输出-1。 Sample Input
例如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 ii, P ii,中间用空格分隔,分别表示到下一个城市的距离和当地的油价(1 <= D ii, P ii <= 1000000)。 Output输出走完整个旅程的最小花费,如果无法从起点到达终点输出-1。 Sample Input
3 15 10 2 9 1 8 3Sample Output
41
代码如下:
思路都在下面。
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<iostream>
using namespace std;
struct node
{
long long int d;
long long int p;
} a[100005];
long long ans,n,T,d,p;
long long int st=1,ed=1;
long long int cnt;
//a[i].d表示的是该油站最多能加多少的油量,加满。
//a[i].p表示的是该油站的价钱。
int main()
{
scanf("%lld%lld",&n,&T);
for(int i=1; i<=n; i++)
{
scanf("%lld%lld",&d,&p);
//有cnt去收集以前的存储下来的油量。
cnt=0;
//如果里程数超过油量储存数
if(d>T)
{
printf("-1");
return 0;
}
//如果之前价格少于你的价格,就拿完你的油量。
//如果之前油量价格大于现在的价格的油价,就退出,更换价格。
for(int i=st; i<ed; i++)
{
if(p>a[i].p)
cnt+=a[i].d;
else
ed=i;
}
//比较存起来的油量够不够存满。
//如果收集来的油量,没有油箱将存满,
if(cnt<T)
{
//如果说存起来的油量,不足那么我们只有买现在的油了。
a[ed].p=p;
//并且将油量修改到能存起来最多的油量。
a[ed].d = T-cnt;
ed++;
}
//开始拿油,减少。
while(st<ed)
{
//从之前的开始拿油量,因为最先用的就是之前的存起来的
if(a[st].d<=d)
{
ans += a[st].d*a[st].p;
d-=a[st].d;
st++;
}
else
{
ans+=d*a[st].p;
a[st].d-=d;
d=0;
}
if(d<=0)break;
}
}
printf("%lld",ans);
return 0;
}