2 徒步旅行中的补给问题 | 豆包MarsCode AI刷题

206 阅读4分钟

问题描述

小R正在计划一次从地点A到地点B的徒步旅行,总路程需要 N 天。为了在旅途中保持充足的能量,小R每天必须消耗1份食物。幸运的是,小R在路途中每天都会经过一个补给站,可以购买食物进行补充。然而,每个补给站的食物每份的价格可能不同,并且小R最多只能同时携带 K 份食物。 现在,小R希望在保证每天都有食物的前提下,以最小的花费完成这次徒步旅行。你能帮助小R计算出最低的花费是多少吗?

测试样例

样例1:

输入:n = 5 ,k = 2 ,data = [1, 2, 3, 3, 2]
输出:9

样例2:

输入:n = 6 ,k = 3 ,data = [4, 1, 5, 2, 1, 3]
输出:9

样例3:

输入:n = 4 ,k = 1 ,data = [3, 2, 4, 1]
输出:10

题目解析

这个题目可以采用动态规划的方法来解决。其基本思想也是将待求解的问题分解成若干个子问题,先求解子问题,然后从这些子问题的解中得到原有问题的解。在这个问题中,我们从第一天开始,根据前一天的状态求解每天中不同状态下的最小花费,再求解下一天的最小花费,由此一步步的到原有问题的解。

题目中没有定义初始状态,因此根据测试样例我们可以给出以下定义,第一天初始时,小R携带的食物为 0 份,然后小R经过补给站购买食物,之后小R消耗一份食物,并到达第二天的补给站。在我们的定义中,每天中,小R首先到达补给站购买食物,之后才消耗一份食物。因此我们可以定义一个二维数组cost_matrix,其中cost_matrix[i][j]表示第 i+1 天小R购买食物后,身上携带 j+1 份食物所需的最小花费。矩阵最后一行代表最后一天经过补给站后小R身上所携带食物数量,小R在最后一天还需消耗一份食物,因此 cost_matrix[-1][0] 即为完成这次徒步旅行的最低花费。

代码解析

以下是以Python语言的题目解析:

def solution(n, k, data):

    # 初始化最小花费矩阵,
    cost_matrix = [[float("inf")]*k for _ in range(n)]

    # 初始化第一天的状态
    for i in range(k):
        cost_matrix[0][i] = data[0]*(i+1)
    # 计算后续每一天的状态
    for i in range(1,n):
        for j in range(k):      # 当前天数携带的食物数量
            for l in range(k):  # 前一天携带的食物数量
                if l-j<=1:
                    cost = data[i]*abs(l-j-1)   # 计算从前一天状态转移到今天状态的成本
                    # 更新今天携带特定数量食物的最小成本
                    cost_matrix[i][j] = min(cost_matrix[i][j],cost_matrix[i-1][l]+cost)

    return cost_matrix[-1][0]

让我们逐步解析这段代码:

初始化成本矩阵

cost_matrix = [[float("inf")]*k for _ in range(n)]

这里创建了一个大小为 n x k 的二维列表 cost_matrix,用来存储第 i+1 天小R购买食物后,身上携带 j+1 份食物所需的最小花费。初始值设置为无穷大 (float("inf")) 表示尚未计算出到达这些位置的成本。

初始化第一天的成本

for i in range(k):
    cost_matrix[0][i] = data[0]*(i+1)

动态规划计算过程

for i in range(1,n):
    for j in range(k):
        for l in range(k):
            if l-j<=1:
                cost = data[i]*abs(l-j-1)
                cost_matrix[i][j] = min(cost_matrix[i][j],cost_matrix[i-1][l]+cost)

这部分是动态规划的核心部分。它遍历数组中的每个元素(从第二个元素开始,即 i=1i=n-1)以及所有可能的状态 j 和前一位置的所有可能状态 l,即在第 i+1 天,小R在经过补给站后身上剩余 j 份食物这一状态,与前一天小R在经过补给站后身上剩余 l 份食物这一状态之间的关系。如果状态 l 和状态 j 的差值不超过 1,此条件是去除当天小R身上剩余食物比前一天剩余食物-1还少的状态,则计算从状态 l 转换到状态 j 的成本,并更新到达当前位置状态 j 的最小成本。

返回原问题结果

return cost_matrix[-1][0]

返回最后一天(数组的最后一个位置)且处于状态 0 ,即剩余一份食物的最小成本。

个人体会

50.优化青海湖至景点X的租车路线成本这道题与本题类似,都是动态规划类题目,可以做做那道题加强对动态规划方法的理解