正如@randomA建议的那样,我们将分两个阶段进行:我们首先找到将要切割的木棍组,然后最小化切割的次数。
就像问题中的特殊情况一样,我们对棒进行排序/命名,以便。这需要时间。 ø (Ñ 登录Ñ )大号1个≥ 大号2≥ ⋯ ≥ 大号ñØ (ñ 日志n )
正如@ user1990169指出的那样,我们永远不必裁切。我≥ ķ
在第一阶段,我们采用二进制搜索来查找号码,,使棒可以切成至少尺寸的片(加上一些小件) ,但不能将木棍切成个大小为碎片。这将花费时间。1 ≤ 小号≤ ķ 1 ,... ,小号ķ 大号小号 1 ,... ,s ^ - 1 ķ 大号小号- 1 Ö (ķ 日志ķ )s1 ≤ 小号≤ ķ1 ,… ,sķ大号s1 ,… ,s − 1ķ大号s − 1Ø (ķ 日志ķ )
如果,则此值为最佳大小,我们可以跳过第二阶段。大号s − 1= Ls
否则,我们知道最佳尺寸满足,如果则是通过将至少一根木棍切成相等大小的块而得到的。第二阶段将确定:大号小号- 1 > ö ≥ 大号小号 ö > 大号小号 ö öØ大号s − 1> Ò ≥ 大号so > LsØØ
对于每个棒,,确定一组候选的尺寸如下:如果切割成尺寸的片转动棒插入片(包括较短的,如果有的话),则该候选此stick是所有值,其中和。(有关为什么这些是唯一的候选大小,请参见@ user1990169的答案。)1 ≤ 我≤ 小号大号小号ř 我大号我一世1 ≤ 我≤ 小号大号s[R一世 Ĵ≤[R我大号我大号一世ĴĴ ≤ [R一世大号一世Ĵ< Ls − 1
保持每个候选大小的发生频率。使用平衡搜索树,这可以在,因为候选大小的总数受约束。Σ 我ř 我 ≤ 2 ķØ (ķ 日志ķ )∑一世[R一世≤ 2 ķ
现在,最常出现并导致有效切割的候选尺寸是为我们提供最佳解决方案的尺寸。此外,如果任何候选尺寸导致有效切割,则任何较小尺寸也将导致有效切割。
因此,我们可以再次使用二进制搜索来找到导致有效切入的最大候选长度。然后我们迭代候选长度的集合,直到该阈值,并在找到其中最大的一个。O (k )Ø (ķ 日志ķ )Ô (ķ )
如果我们忽略(或不必这样做)初始排序,则总共可以得到或的运行时。O (k log k )Ø (ñ 日志n )Ø (ķ 日志ķ )