题目:
小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
代码
import heapq
def solution(n, k, data): # 初始化最小堆和总花费 heap = [] total_cost = 0 price_map = {}
# 遍历每一天
for day in range(n):
# 将当前补给站的价格加入最小堆
heapq.heappush(heap, data[day])
price_map[data[day]] = price_map.get(data[day], 0) + 1
# 如果当前天数大于等于 K,移除超出 K 天范围的补给站价格
if day >= k:
old_price = data[day - k]
price_map[old_price] -= 1
if price_map[old_price] == 0:
del price_map[old_price]
# 从最小堆中取出价格最低的补给站购买食物
while heap and heap[0] not in price_map:
heapq.heappop(heap)
total_cost += heap[0]
return total_cost
测试样例
print(solution(5, 2, [1, 2, 3, 3, 2])) # 输出: 9 print(solution(6, 3, [4, 1, 5, 2, 1, 3])) # 输出: 9 print(solution(4, 1, [3, 2, 4, 1])) # 输出: 10# Edit your code here
思路:
使用贪心算法和优先队列(最小堆)来实现
- 使用最小堆:维护一个最小堆来存储当前可以购买食物的补给站的价格。
- 模拟每天的购买:每天从最小堆中取出价格最低的补给站购买食物,确保每次购买的食物数量不超过
K份。 - 更新最小堆:当到达新的补给站时,将其价格加入最小堆,并移除超出
K天范围的补给站价格。
解题步骤
-
初始化:
- 创建一个最小堆
heap。 - 初始化总花费
total_cost为 0。 - 初始化一个字典
price_map来记录每个补给站的价格。
- 创建一个最小堆
-
模拟每天的购买:
- 对于每一天,从最小堆中取出价格最低的补给站购买食物。
- 更新总花费。
- 将当前补给站的价格加入最小堆。
- 移除超出
K天范围的补给站价格。
-
返回结果:
- 返回总花费
total_cost。
- 返回总花费
代码解释
-
初始化:
heap = []:创建一个空的最小堆。total_cost = 0:初始化总花费为 0。price_map = {}:初始化一个字典来记录每个补给站的价格及其出现次数。
-
遍历每一天:
-
heapq.heappush(heap, data[day]):将当前补给站的价格加入最小堆。 -
price_map[data[day]] = price_map.get(data[day], 0) + 1:更新price_map,记录当前补给站的价格及其出现次数。 -
if day >= k:如果当前天数大于等于K,移除超出K天范围的补给站价格。old_price = data[day - k]:获取K天前的补给站价格。price_map[old_price] -= 1:减少price_map中该价格的出现次数。if price_map[old_price] == 0:如果该价格的出现次数为 0,从price_map中删除该价格。
-
while heap and heap[0] not in price_map:从最小堆中移除已经不在price_map中的价格。 -
total_cost += heap[0]:从最小堆中取出价格最低的补给站购买食物,并更新总花费。
-
-
返回结果:
return total_cost:返回总花费。