1 条题解
-
0
题解
思路
把每个原数视为若干最终因子的乘积。小范围直接枚举乘法划分;更大范围从大到小枚举允许的因子下界,并动态维护每个数所需的最小上界。
1. 操作的本质
不断把 拆成 ,最终得到的是若干个大于 的整数,它们的乘积仍为 。因此,对每个原数,我们是在选择它的一种乘法划分。数 无法被操作,只能保留为 。
做法
子任务 1:枚举乘法划分
当 时,可以递归枚举每个数的所有最终乘法划分。对所有原数的划分方案做深度优先搜索,维护已经选出的因子的最小值和最大值,即可得到最小差值。
这是一个直接依据操作定义得到的独立算法。
固定因子下界
设当前允许出现的最小因子为 。令 表示把 拆成若干个不小于 的因子后,最大因子的最小可能值。
从大到小枚举 。起初保留 本身,所以 。当新允许因子 时,若 是 的倍数并且 ,可以先取出一个因子 ,再最优拆分 :
$$f[x]\leftarrow\min\bigl(f[x],\max(L,f[x/L])\bigr).$$按照 的顺序更新时, 已经包含重复使用因子 的情形。
只有 时,所有原数都能使用当前下界。此时所需的最小上界为
候选答案为 。若集合中含有 ,还要用 计算一次;因子 不能参与拆分,所以不执行转移。
子任务 2:逐次扫描原数组
对每个 完成上述转移后,扫描全部 求 。复杂度为
足以通过 。
子任务 3:有序映射维护当前最大值
用有序映射记录当前各个上界对应的原数组元素个数。每当 变小时,删除旧上界的出现次数并加入新上界;映射末尾就是当前最大值。复杂度多一个对数,适合 。
子任务 4:频次数组维护当前最大值
用 记录当前有多少个原数组元素的 等于 。当某个 变小时,按照 在原数组中的出现次数,把对应计数从旧值移到新值。再用一个只会递减的指针维护最大的非空位置,就能在 均摊时间得到 。
调和级数给出全部转移次数为 。
6. 正确性证明
引理 1 对固定下界 ,转移结束后, 等于所有因子均不小于 的乘法划分中最大因子的最小值。
证明:保留 对应单因子划分。任何使用新因子 的划分都能去掉一个 ,剩余部分是 的合法划分;转移恰好取二者最大值。反之,每次转移都会构造出一个乘积为 且所有因子不小于 的合法划分。按 递增更新还覆盖了多个 。归纳可得结论。
引理 2 对固定 ,使全部最终因子不小于 时,可能达到的最小全局最大值为 。
证明:每个原数都必须至少达到其最优上界 ,所以上式是下界;分别采用达到 的划分即可同时达到该上界。
定理 算法输出最小可能平衡值。
证明:任一最终集合都有实际最小值 ,算法枚举到该 时,由引理 1、2 得到不劣于该方案的候选值。另一方面,每个候选值都由合法划分构造,所以不会小于真实最优值。两边结合即得结论。
复杂度
子任务 1 的复杂度为所有乘法划分组合数乘以每次合并的常数代价。子任务 2 的时间复杂度为 。子任务 3 的时间复杂度为 。满分算法的时间复杂度为 。后三者的空间复杂度均为 。
- 1
信息
- ID
- 1322
- 时间
- 5000ms
- 内存
- 512MiB
- 难度
- 10
- 标签
- 递交数
- 1
- 已通过
- 1
- 上传者