17 -> 8 -> 4 -> 2 -> 1 -> 1 -> 9 -> 5 -> 3 -> 2You can get more than two per round, but it won't be by much. To verify this, I wrote a quick and dirty program that calculated how many lengths were generated by each s from 1 to 100,000. The maximum value was 33. That's a proof by cosmo, but I'll take it.
Stick 11 Stick 4 canbreak numbreaks
-------------- -------------- --------- ---------
Length Breaks Length Breaks Key Val Key Val
11 0 4 0 11 1 11 0
6 1 2 1 6 1 6 1
5 1 1 2 5 1 5 1
3 2 4 1 4 0
2 2 3 1 3 2
1 3 2 2 2 3
1 2 1 5
As you can see, the only stick lengths where canbreak is equal to the
number of sticks are 2 and 1.
Of these, the length with the minimum value of numbreaks is 2, whose val is 3, so the
answer is 3.
void all_breaks(int length, int breaks, map <int, int> &breakmap); |
For each stick length len in the input array, I called all_breaks(len, 0, m), where m was an empty map.
What all_breaks() does is check to see if the length is in the map. If it is, and if its val is less than or equal to breaks, then all_breaks() returns. That's its base case.
If it doesn't return, then it either adds length to the map with a val of breaks, or it updates length's entry in the map to equal breaks. Then, if length is greater than one, it calls itself recursively on the two values that you get when you break length. (You'll note that if length is even, it gets two of the same lengths, but you don't really need to test for this -- if you make the same recursive call twice, it will return instantly on the second one, because the first one has put the length into the map.).
When all_breaks(len, 0, m) returns, the map m will contain all of the information that you need to update canbreak and numbreaks.
If the recursion is confusing to you -- here's what happens when you call all_breaks(11, 0, {}):
all_breaks(11, 0, {}) puts [11,0] into the map and then calls all_breaks recursively on 5 and 6.
all_breaks(5, 1, {[11,0]}) puts [5,1] into the map and then calls all_breaks recursively on 2 and 3.
all_breaks(2, 2, {[5,1],[11,0]}) puts [2,2] into the map and then calls all_breaks recursively on 1 and 1.
all_breaks(1, 3, {[2,2],[5,1],[11,0]}) puts [1,3] into the map and returns.
all_breaks(1, 3, {[1,3],[2,2],[5,1],[11,0]}) returns because 1 is in the map.
all_breaks(2, 2, ..) returns
all_breaks(3, 2, {[1,3],[2,2],[5,1],[11,0]}) puts [3,2] into the map and then calls all_breaks recursively on 2 and 1.
all_breaks(2, 3, {[1,3],[2,2],[3,2],[5,1],[11,0]}) returns, because 2 is in the map with a smaller value.
all_breaks(1, 3, {[1,3],[2,2],[3,2],[5,1],[11,0]}) returns, because 1 is in the map with the same value.
all_breaks(3, 2, ..) returns
all_breaks(5, 1, ..) returns
all_breaks(6, 1, {[1,3],[2,2],[3,2],[5,1],[11,0]}) puts [6,1] into the map and then calls all_breaks recursively on 3 and 3.
all_breaks(3, 2, {[1,3],[2,2],[3,2],[5,1],[6,1],[11,0]}) returns, because 3 is in the map with the same value.
all_breaks(3, 2, {[1,3],[2,2],[3,2],[5,1],[6,1],[11,0]}) returns for ibid.
all_breaks(6, 1, ..) returns
all_breaks(11, 0, ..) returns
The final map is {[1,3],[2,2],[3,2],[5,1],[6,1],[11,0]}. You'll note how it matchs the "stick 11" table above.
After you are sure you have written all_breaks() correctly, go ahead and finish the program.
This means that the running time is n times the sum of: