You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

最小化单日最大糖果支出的气球分配算法求助

解法思路:二分查找最小化最大糖果支出

这是典型的最小化最大值问题,二分查找是解决这类问题的高效方案,完全能适配你给出的大规模输入约束(m高达1e18,n长度1e5)。下面详细拆解解法:

1. 确定二分边界

  • 左边界(left):初始为0,表示完全满足所有天数的气球需求(当sum(n) ≤ m时,这个值就是最终答案)。
  • 右边界(right):初始为max(n[i] * b[i] for all i),表示完全不提供任何气球时的最大单日糖果支出(最坏情况)。

2. 二分查找核心过程

在每次迭代中:

  1. 取中间值mid作为当前尝试的「最大单日糖果支出」。
  2. 计算满足(n[i] - k[i]) * b[i] ≤ mid时,每天所需的最少气球数k[i]:

    推导:由(n[i] - k[i]) * b[i] ≤ mid可得,n[i] - k[i] ≤ mid // b[i](整数除法,因为n[i]-k[i]是非负整数),因此k[i] = max(0, n[i] - (mid // b[i]))。

  3. 累加所有k[i]得到总气球需求total_balloons:
    • 如果total_balloons ≤ m:说明mid是可行的,我们可以尝试更小的最大值,将右边界right更新为mid。
    • 如果total_balloons > m:说明mid太小,无法满足气球总量限制,需要增大最大值,将左边界left更新为mid + 1。
  4. 当left == right时,这个值就是我们要找的最小单日最大糖果支出。

3. 示例验证

以你给出的例子:
m=6,n=[1,3,3,3,2],b=[4,1,5,3,7]

  • 初始left=0,right=15(max(1*4,3*1,3*5,3*3,2*7)的结果)
  • 经过几次二分迭代后,最终得到left=right=5,与示例中的结果完全一致。

4. 时间复杂度分析

  • 二分迭代次数:约为log2(1e18) ≈ 60次(因为n[i]和b[i]最大都是1e9,所以n[i]*b[i]最大为1e18)。
  • 每次迭代需要遍历n数组计算总气球数,时间复杂度为O(len(n))。
  • 总时间复杂度为O(len(n) * log(max(n[i]*b[i]))),对于len(n)=1e5的情况,总操作次数约为6e6,完全高效。

代码实现(Python)

def min_max_candies(m, n, b):
    left = 0
    right = max(ni * bi for ni, bi in zip(n, b))
    
    while left < right:
        mid = (left + right) // 2
        total = 0
        for ni, bi in zip(n, b):
            t = mid // bi
            ki = max(0, ni - t)
            total += ki
            # 提前终止,避免不必要的计算(可选,Python整数无溢出问题)
            if total > m:
                break
        if total <= m:
            right = mid
        else:
            left = mid + 1
    return left

# 测试示例
m = 6
n = [1,3,3,3,2]
b = [4,1,5,3,7]
print(min_max_candies(m, n, b))  # 输出5

这个代码可以轻松处理你提到的大规模输入,Python的整数类型能容纳1e18级别的数值,且遍历1e5元素的开销完全在可接受范围内。

内容的提问来源于stack exchange,提问作者Teodor Dyakov

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.14 08:30:19