In the second part of the discussion, we demonstrated the steel strip segmentation method, except that the solution adopts a top-down strategy.
My personal understanding of top-down strategies:
First, we do not know the answer to a big question, but we can narrow down the problem by adding a known part. Then it becomes the process of solving the answer to this small-scale question. The recursion principle is used to go down layer by layer and finally return to the simplest problem.
In this way, repeated solutions are inevitable. As mentioned in the previous article !!!
Let's take a look at some of the Code in the previous article.
Int get_max (int * price, int * Len, int num, int * P) // the newly added pointer P points to an array of records, subscript for length num-1, we used to record the maximum benefit under the corresponding length num {int result = 0; If (Num> = 1 & P [num-1]> = 0) // The value can be queried from the record table. Return P [num-1]; If (num = 0) // determined by num-len [I] at mark a and if on it, we can see that the next time get_max is called, return 0; For (INT I = 1; I <= 6; I ++) {If (Num> = Len [I-1]) {result = STD: max (result, get_max (price, Len, num-len [I-1], p) + price [I-1]); // mark a} p [num-1] = result; return result ;}
In the code, we can roughly calculate the total number of get_max () calls. First, in constant calls, the num value in the get_max () function is retrieved through 0-num, permission and count as num
In each call, we need to use the for () loop (because of rough calculation). We will not consider the if judgment.
Finally, we calculated the number of calls: num * 6, which is similar to a double loop.
The value of num changes from 0 to the maximum value of num.
The price changes from 1 to 6 and is nested in each change of num, which is obviously a double-layer loop.
Further analysis:
In the above program, the get (... num...) called every time is used to calculate the maximum benefit of the current num. However, a large num is calculated based on a small num and implemented through recursive calling. However, according to the actual running sequence of the program, the maximum benefit of a small num is first calculated, then return to the use of the large num. This is a process of returning results from top to bottom.
Rather than being so troublesome, we should calculate the small num first, and then contribute the value of the Small num to the num larger than it, which reduces the number of recursive calls. (Bottom-up policy)
The requirement for doing so is: we must ensure that when num ranges from 1 to the maximum, each loop will get the maximum benefit of the current num. The code is better:
Void get_max (int * Len, int * price, int N, int num, int * P, int * s) // n indicates the number of segmented types. Num indicates the length of the steel strip, the length of the first truncation under the current num of the p record. The subscript is num. the maximum benefit of the current num of the s record is {s [0] = 0; For (INT I = 1; I <= num; I ++) {int q = 0; // The record that Q is used for the maximum benefit of the second loop under the current num for (Int J = 0; j <n; j ++) {if (I> = Len [J]) {s [I] = s [I-len [J] + price [J];} If (s [I]> q) // when the condition is set, it indicates that the maximum benefit combination under the current num is updated {q = s [I];
p[i]=j; } } s[i] = q; }}
In this way, we can get the biggest benefit and also obtain the segmentation method.
At the same time, it also reduces the complexity of the program to a certain extent.
If you encounter a dynamic planning problem next time, think about it! Understanding is relatively simple. Please advise!
Recursive discussion (ii) continued