T - 汽油补给
有(N+1)个城市,0是起点N是终点,开车从0 -> 1 - > 2...... -> N,车每走1个单位距离消耗1个单位的汽油,油箱的容量是T。给出每个城市到下一个城市的距离D,以及当地的油价P,求走完整个旅途最少的花费。如果无法从起点到达终点输出-1。
第2至N + 1行:每行2个数Dii, Pii,中间用空格分隔,分别表示到下一个城市的距离和当地的油价(1 <= Dii, Pii <= 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个数Dii, Pii,中间用空格分隔,分别表示到下一个城市的距离和当地的油价(1 <= Dii, Pii <= 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; }