分割数字所采取的步骤数

时间:2015-04-11 23:57:04

标签: algorithm numbers

我无法理解这一点:

假设我得到了一个数字9.我想知道拆分所需的最小步骤,以便没有数字大于3。

我一直认为最有效的方法是将每个循环减半。 所以,9 - > 4,5 - > 2,2,5 - > 2,2,2,3总共3个步骤。但是,我刚刚意识到了一种更聪明的方式:9 - > 3,6 - > 3,3,3只是两步......

经过一些研究,步数实际上是(n-1)/ target,其中target = 3在我的例子中。

有人可以向我解释一下这种行为吗?

3 个答案:

答案 0 :(得分:3)

如果我们想将长度为L的长棍切成不大于S的尺寸,我们需要ceiling(L/S)件。每次我们进行新的切割时,我们都会将碎片数量增加1.无论切割的顺序是什么,只要在哪里。例如,如果我们想要将长度为10的棒分成2或更小的块:

 -------------------
0 1 2 3 4 5 6 7 8 9 10

我们应该在以下地方剪掉它:

 ---|---|---|---|---
0 1 2 3 4 5 6 7 8 9 10

任何削减顺序都可以,只要这些是削减。另一方面,如果我们开始把它分成两半:

 ---------|---------
0 1 2 3 4 5 6 7 8 9 10

我们做了一个不是最佳解决方案的削减,我们浪费了我们的时间。

答案 1 :(得分:1)

我真的很喜欢@ user2357112解释为什么减少一半不是正确的第一步,但我也喜欢代数,你可以用归纳证明ceil(n / target) - 1是最优的。

首先让我们证明您始终可以ceil(n / target) - 1步骤。

如果n <= target,显然不需要步骤,那么公式有效。假设n > target。将n拆分为targetn - target(1步)。通过归纳,n - target可以在ceil((n - target)/target) - 1步骤中拆分。因此,步骤总数为

  1 + ceil((n - target) / target) - 1

= 1 + ceil(n / target) - target/target - 1

= ceil(n / target) - 1.

现在让我们证明你不能在少于ceil(n / target) - 1步骤的情况下做到这一点。如果n <= target,这很明显。假设n > target,第一步是n -> a + b。通过归纳,a至少需要ceil(a / target) - 1步,而b至少需要ceil(b / target) - 1步。因此,所需的最小步骤数至少为

   1 + ceil(a / target) - 1 + ceil(b / target) - 1

>= ceil((a + b) / target) - 1                using ceil(x) + ceil(y) >= ceil(x + y)

 = ceil(n / target) - 1                      using a + b = n

答案 2 :(得分:0)

每个n都可以被认为是首先放在队列中的\ lfloor n / target \ rfloor目标元素的优先级队列,以及一个值为n%target的元素。每次从队列中删除元素时,都会将其放回队列中。删除除最后一个元素之外的所有元素:您已经清除了\ lfloor(n-1)/ target \ rfloor元素。如果最后一个元素小于或等于目标,我们就完成了。如果它大于目标,我们就会产生矛盾。所以,在\ lfloor(n-1)/ target \ rfloor步骤之后,我们有一个只包含小于或等于target的元素的队列。