问题描述
小U计划进行一场从地点A到地点B的徒步旅行,旅行总共需要 M 天。为了在旅途中确保安全,小U每天都需要消耗一份食物。在路程中,小U会经过一些补给站,这些补给站分布在不同的天数上,且每个补给站的食物价格各不相同。
小U需要在这些补给站中购买食物,以确保每天都有足够的食物。现在她想知道,如何规划在不同补给站的购买策略,以使她能够花费最少的钱顺利完成这次旅行。
M:总路程所需的天数。N:路上补给站的数量。p:每个补给站的描述,包含两个数字A和B,表示第A天有一个补给站,并且该站每份食物的价格为B元。
保证第0天一定有一个补给站,并且补给站是按顺序出现的。
测试样例
样例1:
输入:m = 5 ,n = 4 ,p = [[0, 2], [1, 3], [2, 1], [3, 2]]
输出:7
样例2:
输入:m = 4 ,n = 3 ,p = [[0, 3], [2, 2], [3, 1]]
输出:9
解题思路
- 小U每天需要一份食物,共需要
M份食物。 - 她只能在有补给站的日子购买食物。
- 她可以在补给站购买任意数量的食物(不限购买量),并携带多天的食物。
- 目标是以最小的总花费,购买足够的食物完成旅程。
贪心算法 是一种在每一步选择中都采取在当前状态下最好或最优(即最有利)的选择,从而希望导致结果是全局最好或最优的算法策略。
为了使总花费最小,我们需要在价格最低的补给站购买尽可能多的食物。具体策略如下:
-
维护当前的最小价格:
- 在旅行过程中,始终使用到当前为止遇到的最小价格来购买食物。
-
购买当天所需的食物:
- 每天只购买当天所需的1份食物,但购买价格是当前最小价格。
实现步骤
-
初始化变量:
current_price:当前最小价格,初始化为补给站0的价格。total_cost:总花费,初始化为0。
-
遍历每一天:
- 如果当天有补给站,且价格比当前最小价格更低,更新
current_price。 - 使用
current_price购买当天的食物,更新total_cost。
- 如果当天有补给站,且价格比当前最小价格更低,更新
代码解释
def solution(m: int, n: int, p: list[list[int]]) -> int:
# 初始化一个数组,存储每一天的价格(如果有补给站),否则为无限大
prices = [float('inf')] * m
for day, price in p:
if day < m:
prices[day] = price
total_cost = 0
current_price = float('inf')
for day in range(m):
# 如果当天有补给站,且价格更低,更新current_price
if prices[day] != float('inf'):
if prices[day] < current_price:
current_price = prices[day]
# 每天消耗一份食物,累加当前的最低价格
total_cost += current_price
return total_cost
if __name__ == "__main__":
print(solution(5, 4, [[0, 2], [1, 3], [2, 1], [3, 2]]) == 7)
算法复杂度分析
- 时间复杂度:
O(M),需要遍历每一天。 - 空间复杂度:
O(N),用于存储补给站信息的字典。
总结
在这道题中,通过贪心策略能够有效地规划小U的食物购买计划,从而以最小的花费完成整个徒步旅行。在存在每日购买限制的情况下,最佳策略是维护当前最小价格,并每天购买当天所需的食物。