蛋糕工厂产能规划解析| 豆包MarsCode AI刷题

71 阅读9分钟

题目背景与分析

问题描述

小明经营了一家蛋糕工厂。工厂初始有 mm 台机器和 ww 名工人,生产 nn 个蛋糕需要尽可能短的天数。工厂每天能生产的蛋糕数量是 m×wm \times w(机器数和工人数的乘积)。为了提升效率,小明可以通过消耗一定数量的蛋糕(每个单位 pp 个蛋糕)购买新的机器或工人。

具体规则如下:

  1. 小明可以选择生产蛋糕,或者用蛋糕购买更多的机器或工人。
  2. 目标是通过最优的策略,尽可能少的天数完成 nn 个蛋糕的生产。

解题思路与策略

1. 核心问题

如何权衡 生产蛋糕购买设备

  • 如果直接生产所需蛋糕数更快,则应该直接生产;
  • 如果购买新的机器或工人能加速未来的生产速度,则应该优先购买。

关键点在于每一步动态选择 最优策略,即:

  • 判断当前生产直接完成任务的时间;
  • 判断购买设备后能否缩短生产时间。

2. 贪心优化

  1. 购买设备的优先级

    • 每次优先选择增加当前较少的一方(机器或工人),使 mwm≈ w,从而最大化每天生产的蛋糕数量。
  2. 动态调整

    • 每次更新当前蛋糕数 candiescandiescandies\text{candies}、设备数 m,w,m,w, 以及已用天数 daysdaysdays\text{days},并重复评估下一步操作。
  3. 等待策略

    • 如果当前蛋糕不足以购买设备,则需要模拟等待天数,直到生产足够蛋糕购买设备为止。
  4. 提前停止

    • 每次购买设备后重新评估,如果直接生产能完成目标,则立即停止购买,直接完成任务。

3. 详细流程

  1. 初始化参数:

    • 当前机器数 m,工人数 w,购买设备成本 p,目标蛋糕数 n。
    • 初始蛋糕数量 candies=0candies=0,已用天数 days=0days=0
  2. 循环模拟:

    • 计算如果直接生产完成目标所需的天数 remainingdaysremaining_{days}

    • 判断是否需要购买设备:

      • 如果当前蛋糕数candies<p candies<p,模拟等待生产到够购买所需蛋糕的时间;
      • 用最优策略购买设备,优先平衡机器和工人数量。
    • 更新状态:增加当前生产的蛋糕数,增加天数。

  3. 当总蛋糕数 candiesncandies≥n 时停止,返回总用天数。


图解流程

以示例m=3,w=1,p=2,n=12m=3,w=1,p=2,n=12 m=3,w=1,p=2,n=12m=3, w=1, p=2, n=12 为例:

步骤当前机器数 m工人数 w当前蛋糕数 candiescandies已用天数 daysdays操作描述
13100生产 33 个蛋糕
23131购买 2 台机器,更新 m=5m=5
35111生产 55 个蛋糕
45162再购买 1 台机器和 1 名工人
56202生产 1212 个蛋糕,完成

代码解析

def solution(m, w, p, n):
    # 初始化变量
    candies = 0   # 当前拥有的蛋糕数量
    days = 0      # 已用的天数
    min_days = float('inf')  # 最少天数初始化为正无穷

    while candies < n:
        # 判断如果直接等待是否能更快完成任务
        remaining_days = (n - candies + m * w - 1) // (m * w)  # 剩余目标所需天数
        min_days = min(min_days, days + remaining_days)

        # 如果当前蛋糕数不足以购买设备,则生产到够为止
        if candies < p:
            # 计算需要生产到够购买设备的时间
            time_to_produce = (p - candies + m * w - 1) // (m * w)
            days += time_to_produce
            candies += time_to_produce * m * w

        # 使用蛋糕购买设备,优先增加较少的一方
        candies -= p
        if m <= w:
            m += 1  # 增加机器数
        else:
            w += 1  # 增加工人数

        # 更新状态
        candies += m * w  # 增加当天生产的蛋糕数
        days += 1         # 增加天数

    return min(min_days, days)

核心逻辑解析

  1. remaining_days 计算

    • 利用当前产能计算直接完成任务的剩余时间: remainingdays=ncandiesm×wremaining_{days} = \lceil \frac{n - \text{candies}}{m \times w} \rceil
  2. 模拟生产到足够购买

    • candies<pcandies<p 时,无法直接购买设备,则模拟生产 timetoproducetime to produce 天直到满足 candiespcandies≥p
  3. 贪心设备购买

    • 每次购买后使机器数 m和工人数 w尽量接近,从而提高总产能。
  4. 状态更新

    • 每次生产后,更新蛋糕数candies candies、天数 dayday,继续下一轮操作。

测试样例

# 测试样例
print(solution(3, 1, 2, 12))  # 输出: 3
print(solution(10, 5, 30, 500))  # 输出: 8
print(solution(3, 5, 30, 320))  # 输出: 14

复杂度分析

  1. 时间复杂度

    • 每次操作要么直接完成任务,要么通过模拟生产和购买设备调整状态。
    • 最多进行 O(log⁡n) 次设备购买或直接生产的判断,时间复杂度为 O(log⁡n)。
  2. 空间复杂度

    • 仅使用了常数变量,空间复杂度为 O(1)。

思考与拓展

  1. 优化策略

    • 当蛋糕数较大时,可以增加更复杂的动态规划判断,进一步优化设备购买顺序。
    • 当 m, w 不平衡时,可以设计更细致的平衡逻辑。
  2. 其他应用

    • 类似问题在生产调度、资源分配领域有广泛应用,例如优化服务器部署、任务分工等。
    • 这道题目涉及多个算法思想和数据结构的通用方法,以下是详细的阐述:

本题涉及到的算法的一般情况

1. 贪心算法的一般方法

  • 核心思想:在每一步决策中选择局部最优解,期望通过一系列局部最优解得到全局最优解。

  • 适用场景:当问题可以分解为多个子问题,并且子问题的最优解可以保证整体问题的最优解时。

  • 一般步骤

    1. 确定贪心选择的标准,例如最大化收益、最小化成本。
    2. 按照标准从当前状态出发,选择最优的操作。
    3. 更新状态,并继续执行贪心选择,直到达到问题的终止条件。
  • 在本题中的体现

    • 每一步判断是等待直接生产更优还是购买新设备更优。
    • 在购买设备时,优先增加机器或工人较少的一方,最大化生产能力。

2. 动态规划的一般方法

  • 核心思想:将问题分解为多个子问题,通过记录子问题的解,避免重复计算,递推求解最终问题。

  • 适用场景

    • 问题具有重叠子问题和最优子结构。
    • 可以通过状态转移方程将大问题分解为子问题。
  • 一般步骤

    1. 定义状态变量,明确问题的子结构。
    2. 找到状态转移方程,即如何从前一个状态递推到当前状态。
    3. 根据边界条件初始化状态。
    4. 按照递推公式逐步计算,直到得到最终解。
  • 在本题中的体现

    • 将每次购买设备后的状态视为一个子问题,通过状态递推(增加机器或工人后更新生产效率)逐步逼近最优解。

3. 队列模型的一般方法

  • 核心思想:模拟一组任务的先进先出(FIFO)处理逻辑。

  • 适用场景

    • 需要按顺序处理任务,例如生产过程、任务调度等。
    • 每一步操作需要基于前一步的结果进行推进。
  • 一般步骤

    1. 初始化队列,确定初始状态(例如初始的蛋糕数量)。
    2. 每一步从队列中取出当前任务,执行操作。
    3. 将操作结果作为新的任务加入队列。
    4. 重复执行,直到满足停止条件。
  • 在本题中的体现

    • 当前蛋糕不足时,模拟生产过程,相当于蛋糕逐步「入队」直到满足条件。

4. 优先队列模型的一般方法

  • 核心思想:每次从一组候选任务中选择优先级最高的任务处理。

  • 适用场景

    • 需要动态管理多个任务的优先级,例如最短路径、任务调度。
    • 每次任务选择需要权衡收益或成本,选择最优任务。
  • 一般步骤

    1. 初始化优先队列,根据任务的优先级排序。
    2. 每次从队列中取出优先级最高的任务进行处理。
    3. 将处理后的结果加入队列,并重新调整优先级。
    4. 重复执行,直到满足停止条件。
  • 在本题中的体现

    • 当前蛋糕不足以购买时,计算需要等待的天数,这种跳过无效步骤的行为类似于优先队列的「任务挑选」逻辑。

5. 数学优化的一般方法

  • 核心思想:利用数学公式直接计算问题的结果,而不是逐步模拟,避免冗余操作。

  • 适用场景

    • 问题中存在简单的数学关系,可以通过公式推导直接求解。
  • 一般步骤

    1. 分析问题的数学关系,找到公式化的解法。
    2. 优化冗余计算,将多次循环操作转换为一次性计算。
    3. 用数学公式代替复杂逻辑,减少计算复杂度。
  • 在本题中的体现

    • 使用公式剩余目标蛋糕数当前每天产量 \lceil\frac{\text{剩余目标蛋糕数}}{\text{当前每天产量}} \rceil 快速计算等待天数,而不是逐天模拟生产。

6. 问题建模的一般方法

  • 核心思想:将实际问题抽象为数学问题或算法问题,通过模型解决实际需求。

  • 适用场景

    • 实际问题需要优化过程,例如生产调度、资源分配、路径规划。
  • 一般步骤

    1. 分析问题背景,明确核心目标(如最短天数、最低成本)。
    2. 抽象问题的变量和约束条件,定义状态和操作。
    3. 确定解决问题的算法或数学模型,设计求解流程。
    4. 验证模型的合理性,并根据实际问题需求进行调整。
  • 在本题中的体现

    • 通过蛋糕生产、设备购买抽象为「状态转移」问题,目标是最小化完成生产目标的天数。

7. 复杂度分析的一般方法

  • 核心思想:从算法的时间复杂度和空间复杂度两个方面分析其效率。

  • 适用场景

    • 需要评估算法性能,特别是在输入规模较大的情况下。
  • 一般步骤

    1. 时间复杂度:分析主要操作的执行次数或增长趋势。
    2. 空间复杂度:分析算法中使用的额外存储空间。
    3. 结合最坏情况和平均情况评估算法的整体性能。
  • 在本题中的体现

    • 时间复杂度:跳过冗余操作后,每次购买设备显著增加生产效率,复杂度近似 O(log⁡n)O(\log n)。
    • 空间复杂度:仅使用常量级变量,无需额外存储,复杂度为 O(1)O(1)。