小F的糖果工厂挑战题解
问题描述
小F的糖果工厂能够生产 n 种不同种类的糖果,糖果的编号从 1 到 n。每天,工厂可以生产编号为 i 的 c_i 个糖果。今天,小F接到了一个特殊的订单,订单要求生产 a 包糖果,每包糖果都必须是同一种类的,并且每包糖果的数量不能少于 b 个。你需要帮助小F计算,工厂至少需要多少天才能完成这个订单。
思路解析
- 首先,可以根据每天生产的糖果数量对糖果种类进行降序排序,这样我们可以优先生产最多的糖果种类,从而尽早完成订单。
- 在每一天内,工厂按照排序后的糖果种类进行生产。每种糖果,工厂会根据其生产数量和每包糖果所需的数量来计算当天能生产的包数,并将该包数累计到总包数上,就算一天成产不了一包也没关系,后文是考虑到这个问题的。
- 结束条件: 当总包数达到订单要求的
a包时,停止生产,返回需要的天数。
解题代码
def solution(n: int, a: int, b: int, candies: list) -> int:
# 排序糖果种类,按生产量降序排列
candies.sort(reverse=True)
days = 0
total_bags = 0
daily_stock = [0] * n # 每种糖果的库存量
i = 0
# 逐天生产糖果,直到完成订单
while total_bags < a:
days += 1
i = 0
for daily_production in candies:
daily_stock[i] += daily_production # 累加生产的糖果数量
# 计算可以完成的包数
while daily_stock[i] >= b:
daily_stock[i] -= b # 每完成一包糖果,减少相应的库存
total_bags += 1
i += 1
return days
if __name__ == '__main__':
# Add your test cases here
print(solution(3, 10, 20, [7, 9, 6]) == 10)
print(solution(4, 5, 15, [3, 10, 8, 4]) == 4)
print(solution(2, 100, 5, [1, 10]) == 46)
解题思路详解
- 排序糖果种类: 首先,将所有糖果的生产量降序排序,这样我们可以优先选择生产数量最多的糖果种类,确保在每一天内尽可能多地完成订单。
- 逐天计算包数: 每天,从生产量最多的糖果开始,计算每天能生产多少包糖果。无论某种糖果的生产量小于还是大于 b,都可以将这些糖果存入数组
daily_stock。每当完成一包糖果,就减少库存并增加已完成的包数。 - 库存管理: 每天的糖果生产量累积到各自的库存中。对于每种糖果,如果库存量超过了
b,则可以根据生产量计算出能完成多少包糖果,并将库存量减少相应的数量。 - 循环直到满足订单: 继续循环直到完成
a包糖果为止。每次循环模拟一天的生产,计算出当天能完成的包数,并更新总的完成包数(可能存在一天一包都没完成的情况)。 - 返回结果: 当总的完成包数达到
a包时,退出循环,返回当前的天数。
复杂度分析
-
时间复杂度:
- 排序糖果生产量:
O(n log n),其中 n是糖果种类的数量。 - 每天的包数计算:最坏情况下需要遍历所有 n 种糖果,每次检查糖果包的完成情况,所以每天的复杂度为
O(n)。 - 假设工厂最坏情况下需要 d 天才能完成订单,最终时间复杂度为
O(d * n)。
- 排序糖果生产量:
-
空间复杂度:
- 我们使用了一个长度为 n 的数组
daily_stock来记录每种糖果的库存,因此空间复杂度为O(n)。
- 我们使用了一个长度为 n 的数组
感受与注意事项
-
边界情况:工厂可能出现一天成产糖果一包都成产不出来,因此这种情况下就不能通过计算每天能生产多少包来解决问题,而且计算每天能生产多少包这种计算方法还可能出现产能浪费的情况,不符合题目要求,因此加入一个库存数组,每天的糖果生产量累积到各自的库存中。
-
感受: 本来以为问题挺简单的,后来发现只计算每天能生产多少包不符合条件也不符合实际,因此我认为考虑问题时应该结合实际多方面考虑。