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

63 阅读6分钟

题目:补给站最优花费问题

问题描述

小U计划进行一场从地点A到地点B的徒步旅行,旅行总共需要 M 天。为了在旅途中确保安全,小U每天都需要消耗一份食物。在路程中,小U会经过一些补给站,这些补给站分布在不同的天数上,且每个补给站的食物价格各不相同。

小U需要在这些补给站中购买食物,以确保每天都有足够的食物。现在她想知道,如何规划在不同补给站的购买策略,以使她能够花费最少的钱顺利完成这次旅行。

  • M:总路程所需的天数。
  • N:路上补给站的数量。
  • p:每个补给站的描述,包含两个数字 A 和 B,表示第 A 天有一个补给站,并且该站每份食物的价格为 B 元。

保证第0天一定有一个补给站,并且补给站是按顺序出现的。


这个问题可以用贪心算法来解决,因为我们需要在尽可能便宜的地方购买食物来满足未来的需求。以下是解决问题的思路:

问题分析

  1. 基本需求

    • 小U需要在路上每一天消耗一份食物。
    • 需要在补给站购买足够的食物来完成整个旅程。
  2. 补给站特点

    • 每个补给站的价格不同。
    • 补给站的分布按照天数递增排列。
  3. 目标

    • 以最小的成本购买足够的食物完成旅行。

算法步骤

  1. 维护当前的食物库存

    • 跟踪当前手头上还有多少食物,确保能覆盖接下来的天数。
  2. 贪心选择购买策略

    • 在补给站购买食物时,优先选择当前最便宜的价格,以满足需求。
    • 如果当前库存的食物无法支撑到下一个补给站,则在当前补给站补充足够的食物。
  3. 模拟每天的需求

    • 遍历所有天数。
    • 每一天的需求为1,减少库存。
    • 如果没有足够的库存去到下一个补给站,计算最小成本补充。
  4. 实现逻辑

    • 使用一个优先队列(小根堆)来存储补给站的价格,动态决定购买数量。

代码实现: import heapq

def min_cost(m, n, p): # 初始化 current_food = 0 # 当前拥有的食物库存 total_cost = 0 # 总花费 index = 0 # 当前补给站索引 heap = [] # 优先队列,存储价格和补给站信息

# 遍历每一天
for day in range(m):
    # 每天消耗一份食物
    current_food -= 1

    # 如果今天有补给站,加入堆中
    while index < n and p[index][0] == day:
        heapq.heappush(heap, p[index][1])  # 价格进入小根堆
        index += 1

    # 如果食物不足,必须购买
    while current_food < 0:
        if not heap:  # 如果堆中没有补给站可用,返回不可能完成的标志
            return -1
        # 从堆中选取最便宜的补给站
        cheapest_price = heapq.heappop(heap)
        total_cost += cheapest_price  # 累计花费
        current_food += 1  # 补充一天的食物

return total_cost

测试样例

print(min_cost(5, 4, [[0, 2], [1, 3], [2, 1], [3, 2]])) # 输出:7 print(min_cost(6, 5, [[0, 1], [1, 5], [2, 2], [3, 4], [5, 1]])) # 输出:6 print(min_cost(4, 3, [[0, 3], [2, 2], [3, 1]])) # 输出:9

以下是使用豆包 MarsCode AI 刷题过程中总结的知识点、学习计划以及工具运用的整理内容。


知识总结

新知识点总结
  1. 贪心算法

    • 思路:优先局部最优解,逐步推导出全局最优。
    • 典型题目:最小食物成本问题、活动安排问题等。
    • 理解:适合对问题的子结构可以单独优化的场景,但并不适合需要回溯的全局优化问题。
  2. 优先队列(小根堆)

    • 核心功能:快速获取最小/最大值,适用于动态场景。
    • 关键操作:插入元素 O(log⁡n)O(\log n)O(logn),弹出最小元素 O(log⁡n)O(\log n)O(logn)。
    • 建议:练习堆的基本操作,了解其在路径规划、区间问题中的应用。
  3. 动态规划(DP)

    • 思路:通过递推公式解决全局最优问题。
    • 关键点:状态定义、转移方程、初始值设定。
    • 建议:从简单的线性 DP 入手,如斐波那契数列,然后逐步提升到二维状态的背包问题等。
学习建议
  • 理解为先:刷题时,优先理解题目要求和基本算法的原理,切勿急于实现代码。
  • 分类练习:将题目按照算法类型(如贪心、堆、动态规划)分类刷题,集中突破难点。
  • 模拟场景:将算法应用于实际生活问题,增强直观理解。

学习计划

制定刷题计划
  1. 明确目标

    • 初期目标:掌握基础算法(排序、查找、递归)。
    • 中期目标:解决经典算法题目(贪心、动态规划、回溯)。
    • 后期目标:挑战综合性题目(如图论、线段树)。
  2. 时间安排

    • 每天投入 1~2 小时,分成以下模块:

      • 知识点学习(20 分钟):复习当天相关算法理论。
      • 刷题实践(60 分钟):集中刷题,覆盖不同难度。
      • 错题分析(20 分钟):记录错题原因,并总结。
  3. 复习机制

    • 每周复盘:分析错题,巩固薄弱点。
    • 每月归纳:整理经典题目及其解法,确保知识点不遗忘。
错题利用
  • 将错题分类归档(如思路错误、代码实现问题等)。
  • 针对性回顾,找到解决类似问题的通用方法。
  • 再次尝试错题,直到能流畅解答。

工具运用

豆包 MarsCode AI 的优势
  1. 智能解析:自动解析题目,提供提示和部分代码。
  2. 逐步引导:通过分步提示帮助理解复杂题目。
  3. 错题诊断:详细分析错误原因,指出代码逻辑问题。
结合其他资源
  1. 与教材结合

    • 配合经典算法书籍(如《算法导论》)加深理解,形成理论-实践闭环。
  2. 借助 LeetCode/Codeforces

    • 提供更广泛的题库练习,同时验证豆包 MarsCode AI 的解题辅助效果。
  3. 视频学习

    • 使用在线课程(如 B站、Coursera)补充算法基础,增强直观理解。
学习建议
  • 多样化资源整合:不要局限于一个平台,多角度获取知识。
  • AI 辅助+主动学习:AI 可提供解题思路,但深入理解需要主动钻研。
  • 反复实践:通过反复练习,将理论转化为熟练技能。

总结

使用豆包 MarsCode AI 刷题,不仅能提升解题速度,还能帮助梳理知识体系。合理规划刷题计划,利用错题强化学习,并结合多种资源,可以实现快速进步。对入门同学来说,重要的是理解算法思想,并逐步积累解决问题的经验。