http://blog.csdn.net/joylnwang/article/details/6769160
The classic dynamic programming problem, the question set is this:
If you have 2 eggs, and a 36-storey building, now you want to know under which floor the eggs will not be broken, and how to use the fewest test times for any answer floor can solve the problem.
- If you drop an egg from a floor, it's not broken, you can continue to use the egg
- If the egg is broken, you can use it to test the egg to reduce a
- All eggs are of the same quality (will be broken on the same floor)
- For an egg, if it is dropped on the floor I drop broken, for any floor not less than I, this egg will be broken
- If you drop the floor I did not break, then for any floor not greater than I, this egg will not be broken
- Dropped from the 1th floor, eggs are not necessarily intact, dropped from the 36th floor, the eggs will not necessarily fall into pieces.
In fact, our ultimate goal is to find a continuous two-storey i,i+1 in the floor I eggs do not break, on the floor i+1 eggs broken, the crux of the problem is that before the test, you do not know where the eggs will be broken, you need to find a test plan, this test plan, no matter where the eggs will be broken in the layer , at most only m tests are required, and in all of these test scenarios, the value of M is minimal.
For only 1 eggs, we have no choice but to start from the 1 floor, up to the level of the test, until the first layer of eggs to break, then we know that the eggs will break the floor is I (or until the top layer, the eggs have not been broken), other testing options are not feasible, because if the 1th test is in any I >1 the floor drops eggs, if the eggs are broken, you will not be sure whether the i-1 layer will also make the eggs broken. So for 1 eggs, the worst case is to make the eggs broken floor number i>=36, at this time, we need to test each floor, a total of 36 times to find the final result, so 1 eggs will be able to solve the 36-storey problem of the minimum test number is 36.
For 2 eggs, 36 stories, you may consider throwing one on the 18th floor, if it is broken, then you will go from the 1th floor to the 17th floor, then use the 2nd Egg test until you find out the answer. If the 1th egg is not broken, then you can still use the 1th egg on the 27 floor of the test, if broken, on the 19th to 26th floor, with 2nd eggs in turn test, if not broken, then with the 1th eggs in the 32 layer test, ..., and so on (somewhat similar to binary search). The worst case scenario for this solution occurs when the result is 17th/18, at which point you need to test 18 times to find the final answer, so the solution to solve the 36-story problem is 18 tests.
Compared to 1 eggs to solve the 36-storey problem, the number of tests achieved halved, but 18 is not to ensure that 2 eggs are resolved, 36 floors problem minimum (the actual minimum value is 8).
We can précis-writers this problem to W (n,k), where n represents the number of eggs that can be used for testing, and K represents the number of floors being tested. For the problem W (2,36) We can think of this, the 1th egg, dropped on layer I (I can be 1~k any value), if broken, then we need to use the 2nd egg, to solve the sub-problem from the 1th to the I-1 (1,i-1), if this egg is not broken, then we need to use these two eggs , solve the sub-problem from the i+1 layer to the 36th layer W (2,36-i), to solve the two problems, we can get a number of attempts p,q, we take the larger of these two times (assuming P), and 1th times in the I-level test of the 1 add, then p+1 is the first time the eggs are still in the I layer to solve W ( 2,36) The minimum number of test times required for TI. For the 36-storey problem, for the first time, we can put the eggs on any layer in the 36 layer, so we can get the test number of the 36 solution T{t1,t2,t3,......, T36}, in which we select the smallest ti, so that for any value in the set T, TJ (1<=j <=36,j!=i), there are TI<=TJ, then TI is the answer to this question. The formula to describe is W (n, k) = 1 + min{max (w (n-1, X-1), W (n, K-x)}, X in {2, 3, ..., k}, where x is the first test of the floor position.
where W (1,k) = K (equivalent to 1 eggs test K-floor problem), W (0,k) = 0,w (n, 0) = 0
So before we calculate W (2,36), we need to calculate the values of all W (1,0),......, W (1,36), W (2,0),......, W (2,35), which can be implemented in a recursive way, with the following code:
[CPP]View PlainCopy
- unsigned int droppingeggspuzzle (unsigned int eggs, unsigned int floors)
- {
- unsigned int i, j, K, T, Max;
- unsigned int Temp[eggs + 1][floors + 1];
- For (i = 0; i < floors + 1; ++i)
- {
- Temp[0][i] = 0;
- Temp[1][i] = i;
- }
- For (i = 2; i < eggs + 1; ++i)
- {
- Temp[i][0] = 0;
- TEMP[I][1] = 1;
- }
- For (i = 2; i < eggs + 1; ++i)
- {
- For (j = 2; J < floors + 1; ++j)
- {
- for (k = 1, max = Uint_max; k < J; ++k)
- {
- t = Temp[i][j-k] > temp[i-1][k-1]? TEMP[I][J-K]: temp[i-1][k-1];
- if (Max > t)
- {
- max = t;
- }
- }
- TEMP[I][J] = max + 1;
- }
- }
- return temp[eggs][floors];
- }
The spatial complexity of the algorithm is O (NK), the time complexity is O (nk^2), for large-scale problems, both space and time complexity are considerable.
This algorithm can calculate the W (2,36) Problem of the minimum test number is 8, but can not give 2 eggs to solve the 36-storey problem of the specific plan, here I give a test plan:
- Test with the first egg in the 8,15,21,26,30,33,35 layer, respectively.
- If the egg is broken in one layer (for example, 26 layers), the previous test pilot is tested from bottom to top, for example (22,23,24,25) until a floor is found that satisfies the condition.
- If the egg is not broken in the 35th level test, then use the egg on the 36th floor to test again.
The scheme guarantees that, regardless of the number of floors that meet the conditions, the answer can be found after a maximum of 8 tests, for example, the target floor is 28 o'clock, the test order of the program is 8,15,21,26,30,27,28, a total of 7 tests, interested readers can try other situations.
The solution to the W (2,36) problem is more elegant, but there is a big mystery, that is generally we see the problem of the surface, often w (2,15), W (2,36), do not know that the reader has not considered, why do not let us calculate 2 eggs test 36 floors of the situation, Instead of 35 or 37 levels? Here is a recursive result table with the previous algorithm to solve W (4,50) problem (where the row represents the number of floors 1~50, the column represents the number of eggs 1~4), we will find that W (2,36) =8,w (2,37) = 9, then is not 2 eggs tested 8 times, up to 36 floor problems can be resolved, There's nothing you can do about the 37 floor?
8 6
1 |
2 |
3 |
4 |
5 |
6 |
&nbs P;7 |
8 |
9 |
ten |
all |
[ |
] |
+ |
- |
|
|
|
|
2 |
+ |
|
all |
|
+ |
+ |
7 |
|
{ |
- |
+ |
+ |
+ |
36 |
+ |
> |
Notoginseng |
|
all |
all |
+ |
all |
| [
] + |
/ | d>46
|
, |
, |
, |
1 |
2 |
2 |
3 |
3 |
3 |
4 |
4 |
4 |
4 |
5 |
5 |
5 |
5 |
5 |
6 |
6 |
6 |
6 |
6 |
6 |
7 |
7 |
7 |
7 |
7 |
7 |
7 |
8 |
8 |
8 |
8 |
8 |
8 |
8 |
9 |
9 |
9 |
9 |
9 |
9 |
9 |
9 |
9 |
|
ten |
ten |
|
1 |
2 |
2 |
3 |
3 |
3 |
3 |
4 |
4 |
4 |
4 |
4 |
4 |
4 |
5 |
5 |
5 |
5 |
5 |
5 |
5 |
5 |
5 |
5 |
5 |
6 |
6 |
6 |
6 |
6 |
6 |
6 |
6 |
6 |
6 |
6 |
6 |
6 |
6 |
6 |
7 |
7 |
7 |
7 |
7 |
7 |
7 |
7 |
7 |
1 |
2 |
2 |
3 |
3 |
3 |
3 |
4 |
4 |
4 |
4 |
4 |
4 |
4 |
4 |
5 |
5 |
5 |
5 |
5 |
5 |
5 |
5 |
5 |
5 |
5 |
5 |
5 |
5 |
5 |
6 |
6 |
6 |
6 |
6 |
6 |
6 |
6 |
6 |
6 |
6 |
6 |
6 |
6 |
6 |
6 |
6 |
6 |
6 |
6 |
Here is a question: n Eggs, Test m (précis-writers to D (N,m)), the maximum can solve the problem of a few floors, through the recursive results of the table observation, we can get as a conclusion
- D (1,m) = m
- D (n,n) = 2^n-1
- D (n,m) {m <= n} = d (m,m)
For the 2nd, take D (for example), we dropped eggs on the 1th 8 floor, if broken, then the second time in the 4 floor dropped eggs, otherwise in the 12 floor dropped eggs, for the case of throwing eggs on the 4 floor, then can be on the 2 floor or 6 floor dropped eggs, so that you can find the answer floor, Method is the same as a binary lookup. For example, the answer floor is 5 of the case, the test sequence is 8,4,6,5.
For the 3rd, if you have 5 eggs to test 3 times, even three test eggs are broken, the remaining 2 eggs will not be useful, so D (5,3) = d (3,3)
After discovering these relationships, we seem to find a solution to the N-egg test m times the maximum number of floors that can be solved. For D (n,m) {n < m}, for the maximum number of floors it can test K, we can construct a scene where the first egg is still on floor I, so that the level I + 1 to the K-level is the maximum number of floors that D (n,m-1) can solve, and 1th to I-1 is D (n-1,m-1) The maximum number of floors that can be resolved, resulting in a recursive relationship d (n,m) = d (n-1,m-1) + 1 + d (n,m-1), and then to D (N,m-1), D (n-1,m-1), and then decomposition according to the above formula, until the three kinds of computable conditions listed just now (n = 1, or M <= n So far, the value of D (n,m) can be obtained by backtracking, and the code is as follows:
[CPP]View PlainCopy
- unsigned int droppingmax (unsigned int eggs, unsigned times)
- {
- if (eggs = = 1)
- {
- return times;
- }
- if (eggs >= times)
- {
- return (unsigned int) POW (2, times)-1;
- }
- return Droppingmax (eggs, times-1) + Droppingmax (eggs-1, times-1) + 1;
- }
According to this algorithm, we can conclude that D (2,5) =15,d (2,8) = 36, that is, 2 eggs Test 5 times can solve the problem of 15 floors, Test 8 times can solve the problem of 36 floors. It can be seen that the person out of this question is not casually looking for two floors to accompany us to play, but the result of serious study on this issue. With this tool, we solve the problem of throwing eggs will be greatly simplified, for n eggs solve K-storey problem we just need to find such a value m, so D (n,m-1) <k<=d (n,m), the code is as follows
[CPP]View PlainCopy
- unsigned int DroppingEggsPuzzle2 (Unsigned int eggs, unsigned int floors)
- {
- unsigned int times = 1;
-
-
- {
- &NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;++TIMES;&NBSP;&NBSP;
- }
- &NBSP;&NBSP;
- < span class= "keyword" >return times;
- }&NBSP;&NBSP;
The time and space complexity of the algorithm is not very good analysis, but are better than the traditional DP algorithm, interested readers can scrutinize, on my machine test 10 eggs, 5000 stories, the second method than the first 100,000 times times faster! Note that the algorithm 2 is also a dynamic programming problem, so you can use a n*m matrix to save intermediate results in the calculation process, the efficiency of the algorithm can be greatly improved!
Whether it is the algorithm 1, or algorithm 2, do not give the n eggs how to pass the M-test, solve the problem of K-floor, I based on the algorithm 2 gives a thought. For the test number m that satisfies the condition D (n,m-1) <k<=d (n,m), D (N,m), and D (n,m-1) are expanded in the manner of D (n,m) = d (n-1,m-1) + 1 + d (n,m-1), In this process, the sequence of iterations in the formula is strictly followed, that is, first D (n-1,m-1), then 1, then D (n,m-1), the order is not chaotic, and then the two results are compared, for example
D (3,5) = d (1,3) +1[2]+d (in) +1[3]+d (2,2) +1[1]+d (+1[3]+d) 2,2 (+1[2]+d) 3,3 ()
D (3,4) = d (+1[2]+d) (2,2) +1[1]+d (3,3)
Each of these individual 1 represents an independent test, and the brackets in these 1 represent the first few independent tests, related to the timing of the separation from the formula, the first separation of 1, the value of which is [1], the second separation of 1, the value is [2], The purpose of these 1 is to break down the K-floor into several sub-parts that can be directly computed. We take out the two different parts D (1,3) +1[2]+d (+1[3]+d (2,2) +1[1], this part indicates that by adding a test, we gain additional detection capability by transforming this part so that the sum equals k-d (n,m-1), The modified part is then combined with the same part of the two to form a new result, the results from front to back, corresponding to the floor from bottom to top of the test plan
In the example above we know that D (3,4) =14, d (3,5) = 25, for the < K <= 25, we use K minus 14 to get the value needed to construct, as far as possible to retain the right side of the calculation, only change the leftmost formula, for example, k = 15, different parts can be replaced with 1 for k = 16 can be replaced with D (+1), for k = 18 can be replaced with D (2,2) +1, for k = 21 can be replaced with D (+1+d (2,2) +1. Taking 21 As an example, we combine the transformation results with the same parts of D (3,4) and D (3,5) to form
D (+1[2]+d) +1[1]+d (2,2) +1[3]+d (2,2) +1[2]+d (3,3)
The following figure illustrates how to test 5 times with 3 eggs, to solve the 21-storey problem, where the rule is that for independent testing, if the test is broken, a subsequent test is performed on the lower floor, and if it is not broken, follow-up tests are performed on the high floor, where the brackets represent the floor/floor range of the test execution.
In fact, for the case of D (n,m-1) <k<d (n,m), there is more than one test scenario that satisfies the condition.
Postscript:
- This is an article of foreign cattle, for the problem of throwing eggs theoretical analysis, let people admire, interested readers can take a look, further deep digging this problem
- For the 2 of the premise of the algorithm, I did not give a mathematical proof, the article of the foreign Daniel is involved, but that article is too long, I did not read.
- According to the recursive relationship of D (N,M), it may be possible to get the formula of this series.
- The problem of throwing eggs is not so much a dynamic programming problem as a mathematical problem in a given scenario, and the more value of the program in this problem lies in the verification conclusion.
Egg throwing problem (egg dropping Puzzle)