青训营X豆包MarsCode 技术训练营第四课 | 豆包MarsCode AI 刷题

45 阅读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

代码

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

思路:

使用贪心算法和优先队列(最小堆)来实现

  1. 使用最小堆:维护一个最小堆来存储当前可以购买食物的补给站的价格。
  2. 模拟每天的购买:每天从最小堆中取出价格最低的补给站购买食物,确保每次购买的食物数量不超过 K 份。
  3. 更新最小堆:当到达新的补给站时,将其价格加入最小堆,并移除超出 K 天范围的补给站价格。

解题步骤

  1. 初始化

    • 创建一个最小堆 heap
    • 初始化总花费 total_cost 为 0。
    • 初始化一个字典 price_map 来记录每个补给站的价格。
  2. 模拟每天的购买

    • 对于每一天,从最小堆中取出价格最低的补给站购买食物。
    • 更新总花费。
    • 将当前补给站的价格加入最小堆。
    • 移除超出 K 天范围的补给站价格。
  3. 返回结果

    • 返回总花费 total_cost

代码解释

  1. 初始化

    • heap = []:创建一个空的最小堆。
    • total_cost = 0:初始化总花费为 0。
    • price_map = {}:初始化一个字典来记录每个补给站的价格及其出现次数。
  2. 遍历每一天

    • 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]:从最小堆中取出价格最低的补给站购买食物,并更新总花费。

  3. 返回结果

    • return total_cost:返回总花费。