One literature will solve the problem of dynamic programming

Dynamic programming is an algorithmic idea used to solve a class of optimization problems. In simple terms, dynamic programming decomposes a complex problem into several sub-problems, and obtains the optimal solution of the original problem by synthesizing the optimal solutions of the sub-problems. It should be noted that dynamic programming will record the solution of each solved sub-problem , so that when the same sub-problem is encountered next time, the previously recorded result can be used directly instead of repeated calculation.

Generally speaking, use recursion or recursion to achieve dynamic programming. Among them, recursion is also called memoized search here .

1. Recursive writing of dynamic programming

Understand how dynamic programming records the solutions of sub-problems to avoid double calculations when encountering the same sub-problems next time

Let’s take the Fibonacci sequence as an example

The Fibonacci sequence is defined as F(0) = 1, F(1) = 1, F(n) = F(n-1) + F(n-2)(n>=2)

int F(int n){
    if(n == 0 || n == 1) return 1;
    return F(n-1)+F(n-2)
}

A lot of repeated calculations will be involved in the above recursive code. Since it must be calculated from n to 1 each time, the actual complexity in this process is as high as O(2^n), which is very terrible.

In order to avoid the above situation, we can open a one-dimensional dp array to record the value of each calculation, as follows:

int F(int n){
    if(n == 0 || n == 1) return 1;
    if(dp[n] != -1) return dp[n];
    else{
        dp[n] = F(n-1) + F(n-2);
        return  dp[n];
    }
}

In this way, the calculated content can be recorded, and when the same content is calculated next time, it can be used directly. This process is called memory search . Through this process, the complexity is reduced from O(2^n) to O(n)

If a problem can be decomposed into several sub-problems, and these sub-problems will appear repeatedly, then the problem is said to have overlapping sub-problems.

2. Recursive writing of dynamic programming

In any case, the summary is achieved with the help of a state transition equation . We derive the concept by understanding an example:

The figure below is a number tower. Starting from the top, at each node, you can choose to go left or right, and walk to the bottom. It is required to find a path that maximizes the sum of the numbers on the path.

Counting tower problem

Thinking analysis:
If you use the greedy algorithm for this problem, you can't guarantee to find the true maximum sum.
When using dynamic programming to consider the problem of counting towers, you can analyze from the top down and calculate from the bottom up.
When starting from the vertex, whether to go to the left or to the right should depend on whether the maximum value can be obtained from the left or the right. The decision can be made only after the maximum value of the left and right paths is obtained. In the same way, the direction of the next layer depends on whether the maximum value of the next layer has been calculated before making a decision. Push it down layer by layer, until the penultimate layer is very clear.
So the first step is to make the following four decisions for the 8 data of the fifth layer:
if it passes through the fourth layer 2, then it must be 19 in the fifth layer 19 and 7;
if it passes through the fourth layer 18, it is in the first The 7 and 10 of the
fifth layer must be 10; if you pass the fourth layer 9, then it must be 10 in the 10 and 4 of the fifth layer;
if you pass the fourth layer 5, it must be in the 4 and 16 of the fifth layer. It is 16;
after a decision, the problem is reduced to one level. The 5-story tower problem is transformed into a 4-story tower problem, and the decision is looped like this... Finally, a 1-level tower problem is obtained.

Algorithm implementation: first use a two-dimensional array data to store the original data of the data tower (in fact, we only use half of the array data, a lower triangular matrix), and then use an intermediate array dp to store the results of each decision-making process (also a Lower triangular matrix).
Initialize dp and copy the last layer of data to dp. dp[n][j] = data[n][j] (j = 1, 2, …, n) where n is the number of floors of the tower.

dp[1][1] = max(dp[2][1], dp[2][2]) + f[1][1]

In the summary of the dynamic programming process, we have dp[i][j] = max(dp[i+1][j], dp[i+1][j+1]) + data[i][j] , finally The result is stored in dp[0][0].
[External link image transfer failed. The source site may have an anti-leech link mechanism. It is recommended to save the image and upload it directly (img-SVWqdCnN-1602582992632)(C:\Users\Lenovo\AppData\Roaming\Typora\typora-user-images\ image-20201013173820061.png)]

#include <bits/stdc++.h>
using namespace std;
int main(){
	int n;
	cin>>n;
	int data[n][n], dp[n][n];
	for(int i = 0; i < n; i++){
		for(int j = 0; j <= i; j++){
			cin>>data[i][j];
		}
	} 
	//1. 初始化边界
	for(int i = 0; i < n; i++){
		dp[n-1][i] = data[n-1][i];
	} 
	//2. 从n-1层开始往上计算dp
	for(int i = n-2; i >= 0; i--){
		for(int j = 0; j <= i; j++){
			//3. 状态转移方程 
			dp[i][j] = max(dp[i+1][j], dp[i+1][j+1]) + data[i][j];
		}
	} 
	for(int i = 0; i < n; i++){
		for(int j = 0; j <= i; j++){
			cout<<dp[i][j]<<' ';
		}
		cout<<endl;
	}
	return 0;
}

/*
输入:
5
9
12 15
10 6 8
2 18 9 5
19 7 10 4 16

打出dp数组:
59
50 49
38 34 29
21 28 19 21
19 7 10 4 16
*/

If the optimal solution of a problem can be effectively constructed from the optimal solution of its subproblems, then the problem is said to have the optimal substructure

to sum up

A problem must have overlapping sub-problems and optimal sub-structures in order to use dynamic programming to solve the problem.

The above is a small summary of learning dynamic programming. Follow-up articles will publish many typical dynamic programming exercises to consolidate these knowledge points.

Insert picture description here

01. The largest continuous subsequence and
02. The longest common non-descending subsequence (LIS)
03. The longest common subsequence
04. The longest palindrome substring
05. 01 Knapsack problem

Guess you like

Origin blog.csdn.net/weixin_44723496/article/details/109057283