升级工具箱:题解¶
解法比较¶
出题人解法的两份实现都把第 \(i\) 类的选择写成因子 \(1+x+\cdots+x^{c_i}\) ,其中 \(c_i\) 是该类可选数量上限,再逐类做朴素卷积,求各总数量的方案数。每一项对应一种合法数量选择,乘法展开恰好枚举全部组合,这是两种实现共同的正确性依据。
记 \(S_i=\sum_{j\le i}c_j\) 、\(S=S_n\) ,朴素卷积时间为 \(O(\sum_i(S_{i-1}+1)(c_i+1))\) ,保留各阶段数组的出题人实现空间为 \(O(n(S+1))\) .Codex(GPT-6)采用的实现利用每个新系数是旧系数一段连续区间的和,用滑动窗口转移,时间为 \(O(n(S+1))\) ,滚动数组空间为 \(O(S+1)\) .滚动存储也可单独用于朴素卷积;时间收益来自窗口和,计数模型不变。
按类型计数¶
第 \(i\) 种可以选 \(0\) 到 \(C_i\) 个,因此答案是多项式
的各项系数。令 \(f_j\) 表示已处理类型中选出 \(j\) 个工具箱的方案数,初始 \(f_0=1\) .加入容量为 \(C_i\) 的类型后:
下标越界的 \(f\) 视为 \(0\) .每个方案唯一分解为“此前类型的方案”和“当前类型数量”,因此转移不重不漏。
滑动窗口¶
随着 \(j\) 增加一,求和窗口加入 \(f_j\) ,移除 \(f_{j-C_i-1}\) .维护一个模 \(100000007\) 的窗口和,每个系数只需常数时间。保存当前和下一层数组,处理完一类后交换。
容量为 \(0\) 的类型仍占用自己的编号,计算后续容量时不能把编号前移。\(n=0\) 时保留初始数组,输出 \(1\) .
由于 \(C_i\le\lfloor1000/i\rfloor\) ,总容量满足
时间复杂度 \(O(n(S+1))\) ,空间复杂度 \(O(S+1)\) .窗口每次只加减一个已取模的系数,使用普通整数并及时归一化即可。