10
$\begingroup$

You have $n$ sticks of arbitrary lengths, not necessarily integral.

By cutting some sticks (one cut cuts one stick, but we can cut as often as we want), you want to get $k<n$ sticks such that:

  • All these $k$ sticks have the same length;
  • All $k$ sticks are at least as long as all other sticks.

Note that we obtain $n + C$ sticks after performing $C$ cuts.

What algorithm would you use such that the number of necessary cuts is minimal? And what is that number?

As an example, take $k=2$ and any $n\geq 2$. The following algorithm can be used:

  • Order the sticks by descending order of length such that $L_1\geq L_2 \geq \ldots \geq L_n$.
  • If $L_1\geq 2 L_2$ then cut stick #1 to two equal pieces. There are now two sticks of length $L_1 / 2$, which are at least as long as the remaining sticks $2 \ldots n$.
  • Otherwise ($L_1 < 2 L_2$), cut stick #1 to two unequal pieces of sizes $L_2$ and $L_1-L_2$. There are now two sticks of length $L_2$, which is longer than $L_1-L_2$ and the other sticks $3 \ldots n$.

In both cases, a single cut is sufficient.

I tried to generalize this to larger $k$, but there seem to be a lot of cases to consider. Can you find an elegant solution?

$\endgroup$
6
$\begingroup$

The first core observation to solving this problem is that the feasibility of a cutting length $l$,

$\qquad\displaystyle \operatorname{Feasible}(l) = \biggl[\, \sum_{i=1}^n \Bigl\lfloor\frac{L_i}{l} \Bigr\rfloor \geq k \,\biggr]$,

is piecewise-constant, left-continuous and non-increasing in $l$. Since the number of necessary cuts behaves similarly, finding the optimal length is just

$\qquad\displaystyle l^{\star} = \max \{ l \mid \operatorname{Feasible}(l) \}$.

Furthermore, as the other answers have proposed, all jump discontinuities have the form $L_i/j$. This leaves us with a discrete, one-dimensional search problem amenable to binary search (after sorting a finite set of candidates).

Note furthermore that we only need to consider the $L_i$ that are shorter than the $k$-largest one, since that one is always feasible.

Then, different bounds on $j$ lead to algorithms of different efficiency.

  • $1 \leq j \leq k$ results in a search space of quadratic size (in $k$),
  • $1 \leq j \leq \lceil k/i \rceil$ in a linearithmic one (assuming the $L_i$ are sorted by decreasing size), and
  • slightly more involved bounds in a linear one.

Using this, we can solve the proposed problem in time $\Theta(n + k \log k)$ and space $\Theta(n + k)$.

One further observation is that the sum in $\mathrm{Feasible}$ grows in $l$ by $1$ for each candidate $L_i/j$ "passed", counting duplicates. Using this, we can use rank selection instead of binar search and obtain an algorithm that runs in time and space $\Theta(n)$, which is optimal.

Find the details in our article Efficient Algorithms for Envy-Free Stick Division With Fewest Cuts (by Reitzig and Wild, 2015).

$\endgroup$
4
$\begingroup$

As @randomA suggested, we will proceed in two phases: We first find the set of sticks that will be cut and then minimize the number of cuts.

As in the special case in the question, we sort/name the sticks so that $L_1 \ge L_2 \ge \dots \ge L_n$. This takes $O(n\log n)$ time.

As @user1990169 pointed out, we never have to cut a piece $i\ge k$.

In the first phase we employ a binary search to find the number $s$, $1\le s \le k$, so that the sticks $1, \dotsc, s$ can be cut into at least $k$ pieces of size $L_s$ (plus some smaller pieces), but the sticks $1, \dotsc, s-1$ can't be cut into $k$ pieces of size $L_{s-1}$. This will take $O(k\log k)$ time.

If $L_{s-1} = L_s$, this value is the optimal size and we can skip phase two.

Otherwise we know that the optimal size $o$ satisfies $L_{s-1} > o \ge L_s$ and if $o > L_s$ then $o$ results from cutting at least one of the sticks into equal sized pieces. Phase two will determine $o$:

For each stick $i$, $1\le i \le s$, determine a set of candidate sizes as follows: If cutting into pieces of size $L_s$ turns the stick into $r_i$ pieces (including the shorter one, if any), then the candidates for this stick are all the values $\frac{L_i}j$, where $j\le r_i$ and $\frac{L_i}j<L_{s-1}$. (See @user1990169's answer for why these are the only candidate sizes.)

Maintain for each candidate size, how often it occured. Using a balanced search tree, this can be done in $O(k\log k)$, since the total number of candidate sizes is bound by $\sum_i r_i \le 2k$.

Now the candidate size that occured most often and leads to a valid cutting is the one that gives us the optimal solution. Furthermore, if any candidate size leads to a valid cutting, any smaller size will lead to a valid cutting as well.

So we can again employ binary search to find the largest candidate length that leads to a valid cutting in $O(k\log k)$. Then we iterate over the set of candidate lengths up to this threshold and find the one with the largest multitude among them in $O(k)$.

In total we get a runtime in $O(n\log n)$, or $O(k\log k)$, if we ignore (or don't have to do) the initial sort.

$\endgroup$
  • $\begingroup$ In the binary search step, how exactly do you check if "the sticks $1,…,s$ can be cut into at least $k$ pieces of size $L_s$"? $\endgroup$ – Erel Segal-Halevi Sep 18 '14 at 7:29
  • $\begingroup$ For $1\le i \le s$ compute $\lfloor L_i/L_s\rfloor$. The sum of these values is the number of pieces you can get. $\endgroup$ – FrankW Sep 18 '14 at 7:31
  • $\begingroup$ "the candidate size that occured most often... is the one that gives us the optimal solution" - why? $\endgroup$ – Erel Segal-Halevi Sep 18 '14 at 7:56
  • $\begingroup$ Becase each time it occurs, we have a stick that gives $t$ pieces with $t-1$ cuts. $\endgroup$ – FrankW Sep 18 '14 at 8:06
  • 1
    $\begingroup$ The total number of cuts is $\frac k2$ in the best case ($\frac k2$ sticks of equal length, all other sticks at most half as long as these and as far as I can see will never be more than $k-1$. (It will definitely never be more than $k$, as every cut yields a stick of the right length and a remainder. But it seems, we can always choose a size so that at least one cut leaves a remainder of the correct length. I don't have a proof for that, though.) $\endgroup$ – FrankW Sep 26 '14 at 17:14
1
$\begingroup$

After you have ordered the sticks in descending order of their lengths, then a stick $L_i$ shall be cut only if all the sticks $L_1, L_2, ... L_{i-1}$ have been cut.

Now since $k < n$, we shall not make any cut on the sticks $L_{k}$ onwards, since we can always have $k$ sticks with length $L_{k}$.

So now instead of $n$, we are dealing with only $k-1$ sticks (possibly adding the $k$-th stick as a whole), and the maximum number of cuts that shall be required in the worst case $= k-1$.

Also, if the optimum number of cuts is $< k-1$, then there shall be at least one set of sticks among those $k-1$ sticks that shall be taken as a whole from 1 original stick (either in parts or in 1 piece), i.e., no part of that original stick shall be left 'untaken'. This is because, by pigeon-hole principle, there shall be at least 1 cut that shall have to produce more than 1 valid stick.

You can then conduct two nested for loops (both till $k$). Outer loop shall denote the stick number $i$ whose all parts have to be taken and inner loop shall denote the number of parts $j$ made of that stick.
For each size $\frac{L_i}{j}$ check whether you can get feasible k sticks by cutting sticks $L_1$ onwards sequentially, and if you can, then update the minimum cuts required so far if the current required number is less.

The total complexity of the above algorithm is $O(nlog(n) + k^3)$

$\endgroup$
1
$\begingroup$

The high level idea would be binary search.

The size of each of the requested k sticks will be at least the smallest stick and at most the biggest one. Because of this, we proceed by using binary search on the size of the middle stick, see what number $k'$ we can obtain, if this $k'$ is more than the given $k$ then we know we need to pick new reference candidate size. So we move to the bigger or smaller using new reference stick. We stop when $k'$ is less than $k$

Once we have found the appropriate reference stick, there is a corner case where we would need to refine the size further. We can sort all the cut sticks by the number of cuts on them and the size of the stick. Pick the one with the least number of cuts and the least size. Reduce the number of cuts on this stick by 1 and making all sub-sticks of this of equal size. This will be the new reference size, check to see if this new size can lead to acceptable $k'$. I admit, I don't know how to bound the running time in this case.

Hopefully, I can see something useful from other answers.

$\endgroup$
  • 2
    $\begingroup$ I think the basic idea of your approach will work. But your description of the algorithm is not clear enough to be sure. Could you add more detailed pseudocode? $\endgroup$ – FrankW Sep 17 '14 at 8:55
  • $\begingroup$ @FrankW I am not too certain about the running time though. I will see what other people have, this is quite an interesting question to ask. $\endgroup$ – InformedA Sep 17 '14 at 11:30

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.