徒步旅行中的补给问题解答(python)

128 阅读3分钟

问题描述

小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

观察样例3,可以发现此时k==理论最低值1,输出结果==data中数值相加,由此可知,经过任意补给站时,如果没有补给,则至少买一份补给来满足途中消耗,以用来行进至下一个补给站,即使到达最后一个补给站也需要消耗,综上,经过每个补给站后当前补给数-1,补给数初始为0,最高不大于k,总共需要经历n个补给站

如果想以最低花费经过所有补给站,无论每个补给站价格如何,最后经历过所有补给站时补给应正好消耗完毕,即补给数==0,而每份补给的价格应是理论可供选择的补给站里价格最低的

如果我们从第一天起,正序处理,首先我们必须在第一个补给站购买第一份,之后需要判断,此时是否已达到补给容量上限,若未达到,我们可以考虑第二次需要消耗时,该份补给从哪里购买,选择可供选择的补给站中价格较低(即第一个或第二个)的,之后判断当前补给容量(此时小R还在第一个补给站)是否达到上限,若达到上限则必须向下一个补给站移动,未达到上限则考虑再下一次的消耗 重复该过程

在这个总过程中,每次补给的消耗都是一个“回头看”的过程,每次消耗补给时,选择之前补给站中可供选择里价格最低的,这样虽然是正序处理数组,但判断过程却是倒序

由此,我们可以倒序处理数组,从经过所有补给站后,消耗最后一份补给的时间节点向前推导,此时我们需要找出最后一份补给的购买位置,其相距当前位置的距离不超过k且不大于剩余补给站数量,然后找到倒数第二份补给的购买位置。。。。。。不用担心是否超过容量,因为容量为k,即使所有能在同一补给站购买的补给数量相加也最多为k

由此可以编写代码如下所示

```def solution(n, k, data):
    # Edit your code here
    newdata=data[::-1]    #倒序排列数组
    Curvalue=float('inf') #设置一个无穷大值,方便之后比较
    Curcost=0             #当前花费,初始值为0
    for i in range(n):    #对于总数n的补给消耗
        for j in range(k):#可选择的补给站
            if(i+j<n and newdata[i+j]<Curvalue  ):#基于当前补给位置i,距离为j的补给站位置不能超过总长度
                Curvalue=newdata[i+j]#更便宜则更新花费
        Curcost+=Curvalue       #此补给花费为理论最低
        Curvalue=float('inf')   #刷新比较值      
    return Curcost              #返回结果