The dynamic programming method is often used to solve optimization problems. Dynamic Programming Algorithm Design steps:
1. Describe the structural characteristics of an optimal solution.
2. Recursion defines the value of the optimal solution.
3. Calculate the value of the optimal solution, usually using a bottom-up approach.
4. Use the computed information to construct an optimal solution.
How to implement Dynamic programming:
top-down method with memo: This method still writes the process in a natural recursive form, but the process saves the solution for each sub-problem (usually stored in an array or hash table). When a solution is required for a sub-problem, the procedure first checks to see if the solution has been saved. If so, the saved value is returned directly, saving the calculation time; otherwise, the sub-problem is calculated as usual.
bottom-up method: This method generally needs to properly define the concept of "scale" of sub-problem, so that any sub-problem can be solved by the "smaller" sub-problem. As a result, we can sort the sub-problems by scale and solve them in order from small to large. When solving a sub-problem, the smaller sub-problems it relies on have been solved and the result has been saved. Each sub-problem only needs to be solved once, and when we solve it (and the first time it encounters it), all of its premise sub-problems have been solved.
Problem: The company buys long steel strips and cuts them to short steel bars for sale. The cutting process itself is not cost-incurred. Company management wants to know the best cutting solution.
Suppose we know that the company sells a length I-inch of steel for the price of Pi (i=1,2, ..., in dollars). The lengths of the rods are all inches. The figure shows a sample of a price list.
Length I 1 2 3 4 5 6 7 8 9 10
Price Pi 1 5 8 9 10 17 17 20 24 30
The problem with cutting steel bars is this: given a length of n-inch steel bars and a price list pi, the cutting scheme makes the sales profit RN the largest.
Of course, if the length of the steel bar of n-inch is large enough, the optimal solution may be that there is absolutely no need for cutting.
For the above price list example, we can observe all the optimal return value RI and the corresponding optimal solution scheme:
R1 = 1, cut solution 1 = 1 (no cut)
R2 = 5, cut solution 2 = 2 (no cut)
R3 = 8, cut solution 3 = 3 (no cut)
R4 = 10, cutting scheme 4 = 2 + 2
R5 = 13, cutting scheme 5 = 2 + 3
R6 = 17, cut solution 6 = 6 (no cut)
R7 = 18, cutting scheme 7 = 1 + 6 or 7 = 2 + 2 + 3
R8 = 22, cutting scheme 8 = 2 + 6
R9 = 25, cutting scheme 9 = 3 + 6
R10 = 30, cut solution 10 = 10 (no cut)
More generally, for RN (n >= 1), we can describe it with the best cut yield of shorter steel bars:
Rn = Max (Pn, R1 + Rn-1, R2 + Rn-2,..., Rn-1 + R1)
first, the steel bar is cut to the length of I and n-i two, and then the optimal cutting yield ri and rn-i are solved for both segments. (the optimal yield for each scenario is the sum of the optimal returns of two segments), as there is no way to predict which scheme will yield the best returns, we must look at all possible I and choose the one with the greatest benefit. If the direct sale of the original steel bar will get the most benefit, We can of course choose not to do any cutting.
#include <iostream> #include <algorithm> #include <vector> #include <utility>using namespace std;/*------------------------------------------------------------------------------------------/* Solution with simple recursive method : Recursive solution for each sub-problem, when encountering the same sub-problem re-solve, focus on understanding the recursive process/* This method the biggest drawback is: whenever n increases 1, the program run time will increase by almost one times,/* Its workload will be explosive growth. /*-------------------------------------------------------------------------------------------*/int cut_rod (int * P,const int &n) {if (n = = 0) return 0;int q = -1;for (int i = 1; I <= n; ++i) {q = max (q, P[i]+cut_rod (P, n-i));} return q;} Using the dynamic programming method: To save the results of their sub-problems when the sub-problem is encountered, when encountering the same sub-problem, it is not necessary to solve the problem again//But to find the sub-problems to be solved directly call//The second method is: top-down cut_tod process, added a memo mechanism int memoized_cut _rod_aux (int *p, int n, int *r) {if (R[n] >= 0) return R[n];int q = -1;if (n = = 0) q = 0;else{for (int i = 1; I <= N; + +i) q = max (q, P[i] + memoized_cut_rod_aux (p, n-i, R));} R[n] = q;//an optimal solution for preserving sub-problems return q;} int Memoized_cut_rod (int *p, const int n) {int r[11] = {0};for (int i = 1; I <= n; i++) r[i] = -1;int Q = Memoized_cut_ro D_aux (P, N, R); return q;} Third method: Bottom-up method int Bottom_up_ut_rod (int *p, int n) {int r[11] = {0};int q = 0;for (int j = 1; j <= N; ++j) {for (int i = 1; I <= J; ++i) q = max (q, p[i] + r[j-i]); r[j] = q;} return r[n];} Refactoring: Not only when the output length is n, the maximum benefit also outputs an optimal cutting scheme pair<vector<int> vector<int>> extended_bottom_up_cut_rod (int *p , int n) {int r[11] = {0};int s[11] = {0};p air< vector<int>, vector<int> > Result;result.first.push_b ACK (0); result.second.push_back (0); for (int j = 1; j <= N; ++j) {int q = -1;for (int i = 1; I <= J; ++i) {if (Q < p[ I] + r[j-i]) {q = p[i] + r[j-i];s[j] = i;}} R[J] = Q;result.first.push_back (R[j]); Result.second.push_back (S[j]);} return result;} Output revenue and scheme void print_cut_rod_solution (int *p,int n) {pair< vector<int>, vector<int> > Result;result = Extended_bottom_up_cut_rod (P, n);vector<int> r = result.first;vector<int> s = result.second;cout << " The maximum yield of steel strip cutting is: "; cout << R[n] << endl;cout << "Best cut Mode:" << endl;while (n > 0) {cout << s[n];n = N-s[n];cout << Endl;}} int main () {char Ch;int p[11] = {0, 1, 5, 8, 9, ten, N, N,,,};int n;while (cin >> N) {cout << "normal recursive party Law: "<< Cut_rod (P, N) << endl;cout <<" top-down with memo: "<< Memoized_cut_rod (P, N) << endl;cout << "Bottom-up:" << Bottom_up_ut_rod (P, N) << endl;print_cut_rod_solution (P, N), cout << "Please enter Y or n:"; cin >> ch;if (ch = = ' n ') break;else{cout << "Please enter continue to enter the appropriate number n:"; continue;}}
Introduction to the algorithm---------steel strip cutting with dynamic programming