【51nod 1288 汽油补给 】 贪心 & 思维

本文介绍了一种算法,用于计算从起点到终点经过一系列城市所需的最低汽油费用。该算法考虑了油箱容量、各城市间的距离及当地油价,通过动态调整加油策略确保最低成本。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

汽油补给
李陶冶 (命题人)
基准时间限制:1 秒 空间限制:131072 KB 分值: 160
有(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

思路 : 用数组保存前面比当前站的油价便宜的站点,在考虑当前站点时,优先加前面的站点还可以加的油量,并且每次仅加到刚好能到达下一个站的油量,多余的保存起来

AC代码:

#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
using namespace std;
const int MAX = 1e5 + 10;
typedef long long LL;
int d[MAX],p[MAX];
int main()
{
    int n,t,ok = 1,l = 1,r = 1;
    LL ans = 0;
    scanf("%d %d",&n,&t);
    while(n--){
        int x,y,sum = 0;
        scanf("%d %d",&x,&y);
        if(x > t) ok = 0;
        if(!ok) continue;
        for(int i = l; i < r; i++)
            if(p[i] < y) sum += d[i]; // 前面的站的油比当前站便宜,优先加
            else r = i; // 不比当前站便宜,没必要在前面站加
        if(sum < t) d[r] = t - sum,p[r++] = y; // 当前站可以加油,再跑多远
        while(l <= r && x)
            if(x < d[l]) ans += (LL)x * p[l],d[l] -= x,x = 0; // 优先在前面站加,因为维护的数组前面的比后面的要便宜
            else ans += (LL)d[l] * p[l],x -= d[l++];
    }
    if(ok) printf("%lld\n",ans);
    else puts("-1");
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值