问题分析
题目要求求解一个优化问题:在给定初始条件下,通过合理分配生产的蛋糕以购买机器和工人,尽快完成生产目标。主要思路是:
- 每天计算现有机器和工人可以生产的蛋糕数量。
- 用生产的蛋糕尽可能购买额外的机器或工人来提升生产速度。
- 模拟每天的生产过程,同时检查是否可以在当前天数内完成订单。
解法思路
为了解决这个问题,我们可以采用二分查找和贪心策略:
- 二分查找最少天数:
初始的天数范围是从 1 到 n / (m × w) + 1(假设每天都满负荷生产)。
二分查找的核心在于验证一个固定天数是否可行,即在这些天内是否能生产出至少 n 个蛋糕。
- 贪心策略验证可行性:
每天尽量用现有蛋糕购买更多的机器或工人,优先保证 m和 w 平衡(即数量相差最小)。
如果某一天蛋糕足够完成任务,则立即停止计算。
核心函数说明
check(days, m, w, p, n)
该函数判断在给定的天数内,是否可以生产出至少 n 个蛋糕。
初始化蛋糕数量 cakes = 0。
模拟每天生产的过程:
根据当前机器和工人数量计算当天生产的蛋糕。
用蛋糕购买新的机器或工人,尽量保持机器和工人的数量接近。
如果某天剩余的天数可以完成目标(通过预测生产量计算),则提前返回 True。
返回是否可以完成任务。
二分查找
通过二分查找调整最少天数:
如果当前天数可以完成任务,则缩小右边界。
如果当前天数不能完成任务,则增加左边界。
def solution(m, w, p, n):
l, r = 1, n // (w * m) + 1
def check(days, m, w, p, n):
cakes = 0
for day in range(1, days + 1):
cakes += m * w
if cakes >= n:
return True
while cakes >= p:
if m < w:
m += 1
else:
w += 1
cakes -= p
if cakes + (m * w * (days - day)) >= n:
return True
return cakes >= n
while l < r:
mid = l + (r - l) // 2
if check(mid, m, w, p, n):
r = mid
else:
l = mid + 1
return l
if __name__ == "__main__":
# 测试用例
print(solution(3, 1, 2, 12) == 3) # True
print(solution(10, 5, 30, 500) == 8) # True
print(solution(3, 5, 30, 320) == 14) # True
代码解释
二分查找的范围
l = 1,r = n // (m × w) + 1 是因为在最极端情况下:
- 生产速度为 m×w每天都不进行购买。
- 最多需要 n/(m×w)天完成目标。
贪心的购买策略
购买策略优先保持机器和工人的数量平衡:
- 如果 m<w,优先增加机器。
- 如果 m≥w,增加工人。
这样可以确保 m×w最大化,提升生产效率。
复杂度分析
-
时间复杂度:
- 二分查找需要 O(log(n)) 次。
- 每次调用
check模拟生产过程,最多运行 O(days),其中天数最多为 n/(m×w)。 - 总体复杂度约为 O(log(n)⋅n/(m×w))。
-
空间复杂度:
- 仅使用常数级别的额外空间,空间复杂度为 O(1)。