【青训入营】青海湖租车之旅

# 问题描述

油价飞升的今天,我们尽量减少花费。我们出门旅游,有时候租车去旅游也是一种不错的方式。这次我们这次旅游是从「青海湖」到「景点 X」,景点 X 可以是「敦煌」、「月牙泉」等,线路的路径是唯一的,假设我们每走 1 km 消耗 1 L 的油,车油箱容量 400L。比如:如果「景点 X」是敦煌,我们在青海湖租车前油箱是 200L 的,在「景点 X」(敦煌)还车的时候也是 200L 的,路上有很多加油站,加油站在青海湖和「景点 X」的连线上。

## 输入格式

第 1 行表示「青海湖」到「景点 X」的距离,距离最远不超过 10000 km。
第 2 行表示接下来 N 行表示 N 个加油站(N 为正整数)。
接下来 N(1 <= N <= 100)行表示,每一个加油站情况。每一个加油站包括距离「景点 X」的距离 a km(0 <= a <= 10000),以及每升汽油的价格 b 元(0 <= b <= 2000),a 和 b 均为正整数。

## 输出格式

如果不能到达目的地「景点 X」,输出 Impossible。
如果能到达目的地「景点 X」,输出最小花费多少元。

**输入样例**:
500
4
100 1
200 30
400 40
300 20

**输出样例**:
4300

def solution(distance, n, gas_stations):
    # Please write your code here
    #线性动态规划
    #n的值在下面的代码中可以发生改变,代表有效的加油站数量

    #将终点距离加到加油站列表中,方便后续处理(相当于把终点当成最后一个加油站了)
    gas_stations.append((distance,0))
    #按照距离加油站的距离长短排序
    gas_stations.sort(key=lambda x:x[0])

    #距离数组,表示每个加油站和前一个加油站的距离
    dis=[0]*(n+1)
    dis[0]=gas_stations[0][0]
    for i in range(1,n+1):
        dis[i]=gas_stations[i][0]-gas_stations[i-1][0]
    

    #dp[i][j]表示到达第i个加油站油量剩余j时的最小花费
    dp=[[float('inf')]*410 for _ in range(110)]
    #起点设置为0
    dp[0][200]=0
     
    #动态规划过程
    for i in range(1,n+1):
        #意味着找到最后一个有效的加油站
        if gas_stations[i-1][0]==distance:
             n=i-1
             break
        #j表示到达第 i 个加油站时油量剩余为 j 的情况,k表示到达第 i - 1 个加油站时油量剩余为 k 的情况
        for j in range(401):
            for k in range(401):
                #如果从当前加油站的前一个加油站出发,到达当前加油站时油量足够,并且当前加油站有油价信息
                if j+dis[i-1]-k>=0 and len(gas_stations[i-1])>1:
                    #更新dp[i][j]为到达当前加油站剩余j的最小花费
                    cost = (j + dis[i - 1] - k) * gas_stations[i - 1][1]
                    dp[i][j]=min(dp[i][j],dp[i-1][k]+cost)
    
    if n<1 or 200+dis[n-1]<0 or dp[n][200+dis[n-1]]==float('inf'):
        return "Impossible"
    return dp[n][200+dis[n-1]]


if __name__ == "__main__":
    #  You can add more test cases here
    gas_stations1 = [(100, 1), (200, 30), (400, 40), (300, 20)]
    gas_stations2 = [(100, 999), (150, 888), (200, 777), (300, 999), (400, 1009), (450, 1019), (500, 1399)]
    gas_stations3 = [(101,), (100, 100), (102, 1)]
    gas_stations4 = [(34, 1), (105, 9), (9, 10), (134, 66), (215, 90), (999, 1999), (49, 0), (10, 1999), (200, 2), (300, 500), (12, 34), (1, 23), (46, 20), (80, 12), (1, 1999), (90, 33), (101, 23), (34, 88), (103, 0), (1, 1)]

    print(solution(500, 4, gas_stations1) == 4300)
    print(solution(500, 7, gas_stations2) == 410700)
    print(solution(500, 3, gas_stations3) == "Impossible")
    print(solution(100, 20, gas_stations4) == 0)
    print(solution(100, 0, []) == "Impossible")

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值