青训营刷题日记6| 豆包MarsCode AI刷题

102 阅读4分钟

优化青海湖至景点X的租车路线成本

在现代生活中,随着油价的不断上涨,出行成本成为我们不得不考虑的重要因素。小F计划从青海湖出发前往一个遥远的景点X进行旅游,为了尽量减少行程中的燃油成本,他希望合理规划加油站的加油顺序和数量,从而最小化从青海湖到景点X的旅行成本。本文将通过Python代码实现这一目标,并提供详细的分析和思考。

问题描述

小F计划从青海湖出发,前往一个遥远的景点X进行旅游。由于油价的不断上涨,他希望尽量减少行程中的燃油成本。车辆的油箱容量为400L,在起始点租车时,车内剩余油量为200L。每行驶1km消耗1L油。沿途设有多个加油站,小F可以在这些加油站补充燃油;到达目标景点X还车的时候,需要保证车内剩余的油至少有200L。

输入输出说明

输入:

  • distance: 从青海湖到景点X的总距离(km),距离最远不超过10000 km。
  • n: 沿途加油站的数量 (1 <= n <= 100)。
  • gas_stations: 每个加油站的信息,包含两个非负整数 [加油站距离起始点的距离(km), 该加油站的油价(元/L)]。

输出:

  • 最小化从青海湖到景点X的旅行成本(元)。如果无法到达景点X,或者到达景点X还车时油料剩余不足200L,则需要返回 -1 告诉小F这是不可能的任务。

测试样例

样例1:

distance = 500
n = 4
gas_stations = [[100, 1], [200, 30], [400, 40], [300, 20]]

输出:4300

样例2:

distance = 1000
n = 3
gas_stations = [[300, 25], [600, 35], [900, 5]]

输出:-1

样例3:

distance = 200
n = 2
gas_stations = [[100, 50], [150, 45]]

输出:9000

样例4:

distance = 700
n = 5
gas_stations = [[100, 10], [200, 20], [300, 30], [400, 40], [600, 15]]

输出:9500

样例5:

distance = 50
n = 1
gas_stations = [[25, 100]]

输出:5000

代码实现与分析

动态规划思路

我们可以使用动态规划来解决这个问题。定义 dp[i][j] 表示在第 i 个加油站加油后,油箱内有 j L油时的最小花费。初始状态是 dp[0][200] = 0,即在起始点有200L油且花费为0。然后逐步计算每个加油站的最优加油策略。

代码实现

import sys

def solution(distance, n, gasStations):
    maxCapacity = 400
    inf = sys.maxsize
    
    # 按照加油站位置升序排序
    gasStations.sort(key=lambda x: x[0])
    
    # 计算每个加油站之间的距离
    dis = [gasStations[0][0]]
    for i in range(1, len(gasStations)):
        dis.append(gasStations[i][0] - gasStations[i-1][0])
    
    # 初始化 dp 数组
    dp = [[inf] * (maxCapacity + 1) for _ in range(n + 2)]
    dp[0][200] = 0  # 初始状态,容量为200,花费为0
    
    # 动态规划计算最小花费
    for i in range(1, n + 1):
        for j in range(maxCapacity + 1):
            for k in range(maxCapacity + 1):
                if j + dis[i-1] - k >= 0 and k >= dis[i-1]:
                    dp[i][j] = min(dp[i][j], dp[i-1][k] + (j + dis[i-1] - k) * gasStations[i-1][1])
    
    # 判断是否可以到达终点
    remaining_fuel = 200 + distance - gasStations[n-1][0]
    
    if remaining_fuel > maxCapacity or remaining_fuel < 0:
        return -1
    
    result = inf
    for i in range(remaining_fuel, maxCapacity + 1):
        result = min(result, dp[n][i])
    
    if result == inf:
        return -1
    
    return result

if __name__ == "__main__":
    # 测试样例
    gas_stations1 = [[100, 1], [200, 30], [400, 40], [300, 20]]
    gas_stations2 = [[300, 25], [600, 35], [900, 5]]
    gas_stations3 = [[100, 50], [150, 45]]
    gas_stations4 = [[100, 10], [200, 20], [300, 30], [400, 40], [600, 15]]
    gas_stations5 = [[25, 100]]
    
    # 测试用例
    print(solution(500, 4, gas_stations1) == 4300)
    print(solution(1000, 3, gas_stations2) == -1)
    print(solution(200, 2, gas_stations3) == 9000)
    print(solution(700, 5, gas_stations4) == 9500)
    print(solution(50, 1, gas_stations5) == 5000)

个人思考与分析

在这个问题中,我们使用了动态规划的方法来解决最小化旅行成本的问题。通过定义状态和状态转移方程,我们能够有效地计算出在不同加油站加油后的最小花费。这种方法的时间复杂度较高,但能够确保找到最优解。此外,我们还需要考虑一些特殊情况,例如无法到达终点或油量不足的情况,这时我们需要返回 -1。

通过上述代码和分析,我们可以看到动态规划在解决此类优化问题中的重要作用。它不仅能够提供精确的解决方案,还能够帮助我们理解问题的结构和求解过程。