有(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<bits/stdc++.h>
#define mod 19260817
#define inf 1000000005
#define pa pair<int,int>
typedef long long ll;
using namespace std;
inline int read()
{
int x=0,f=1;char ch=getchar();
while (ch<'0'||ch>'9'){if (ch=='-')f=-1;ch=getchar();}
while (ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
return x*f;
}
int n,T,d[100005],p[100005];
ll sum[100005],ans;
int r,q[100005],point[100005];
int main()
{
n=read();T=read();
for (int i=1;i<=n;i++)
{
d[i]=read();p[i]=read();
sum[i]=sum[i-1]+d[i];
while (p[q[r]]>=p[i]&&r)
{
point[q[r]]=i;
r--;
}
q[++r]=i;
}
int i=1,t=0;
while (i<=n)
{
if (t<0){printf("-1");return 0;}
if (point[i]==0)
{
if (sum[n]-sum[i-1]<=T)
{
ans+=(ll)max(sum[n]-sum[i-1]-t,0LL)*p[i];
break;
}
else
{
ans+=(ll)(T-t)*p[i];
t=T-d[i];
i=i+1;
}
}
else
{
if (sum[point[i]-1]-sum[i-1]<=T)
{
ans+=(ll)max(sum[point[i]-1]-sum[i-1]-t,0LL)*p[i];
t=max(sum[point[i]-1]-sum[i-1],1LL*t)-sum[point[i]-1]+sum[i-1];
i=point[i];
}
else
{
ans+=(ll)(T-t)*p[i];
t=T-d[i];
i=i+1;
}
}
}
if (t<0){printf("-1");return 0;}
printf("%lld",ans);
return 0;
}