有(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
思路:
1.在当前城市p 在油满的条件下往前寻找首个比城市q的油价低的城市q
(只要找到一个油价低于p的城市q,则可以在q加油,从而费用最小)
2.对城市p,q的油价比较:若 q<=p,则加 dpq 的油量,否则加满油
3.汽车行驶到城市q,重复1—3步骤直到到达终点
* 加油过程需考虑以下情况:1.油箱内是否还有油。2.判断在加满油的情况下到达终点是否会剩下油
** 编程中需注意 爆数据类型
#include<iostream>
using namespace std;
typedef long long LL;
const int MAX_N=100005;
int n,T;
LL ans;
int D[MAX_N],P[MAX_N];
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
LL surplus=0; //long long
cin>>n>>T;
for(int i=0;i<n;++i)
cin>>D[i]>>P[i];
int sum,d,w;
for(int k=0;k<n;k=d)
{
sum=D[k];
d=k+1; w=1e8;
for(int i=k+1;i<n&&sum<=T;sum+=D[i++])
if(w>=P[i]){
d=i; w=P[i];
//找到一个油价低的城市则停止寻找
if(w<=P[k]) break;
}
if(D[k]>T){
ans=-1; break;
}
int dis=0;
for(int i=k;i<d;++i)
dis+=D[i];
if(P[k]>=w){ //加 恰好到达城市p的油
ans+=P[k]*(dis-surplus);
surplus=0;
}else{ //加满油
if(sum>T){ //不能到达终点
ans+=P[k]*(T-surplus);
surplus=T-dis;
}else{ // 可到达终点
ans+=P[k]*(sum-surplus);
break;
}
}
}
cout<<ans<<endl;
return 0;
}