0. First Course
First, before you begin to understand the DP idea, you need to
1. Complete the HDU inside the recursive solution topic exercises (for beginner) that 7 questions (these questions are very simple, the solution please search in the blog), this to you understand DP has a lot of help.
2. There is a certain understanding of recursive search (for example, depth first search, DFS).
I. Recursive and memory search
We start with POJ 3176 to learn this idea. (The topic is very short, please read it quickly)
From the top down, the maximum and the value is nothing more than the two roads to the left and to the right to walk the larger people. In this way, we can write the following important recursive function: (Here I represents the row, J represents the column)
int f (int i, int j)
{
if (i = = n-1) return a[i][j];
return A[i][j] + max (f (i + 1, j), F (i + 1, j + 1));
}
However, when we finished compiling the whole program and passed the sample, we returned a bunch of scarlet text after submitting it:
What happened?
We analyzed the program carefully and found that when we went down from (0,0), the road more and more, and cell division, the final road about 2^n!
It was really scary, and when we got back to God, the program had already collapsed (the stack).
Calm down, kid. Let's take a closer look at the given data, well, a triangular size of data, exactly, n (n+1)/2 digits.
According to the common sense, the actual road is only about n^2, how can it produce exponential level of path number?
Yes, repeat.
Repetitive computations result in the eventual collapse of the program, while reducing duplication is an eternal theme of program optimization.
So, where is the repetition, how do you reduce the repetition of the calculation?
Let's take a look at the sample given by the topic, and we'll focus on the 1 point: we can reach 1 from 7-3 to 1, continue down the surface, or we can reach 7-8 from 1-1 and continue to count down. So, in the code above, we're two times the point at 1! The same encounters also occur in those points below 1. A large number of repetitive computations eventually lead to the generation of a number of paths.
So, we might as well start by calculating a point before we see if it has been computed.
What do you think? Well...... Maybe we need an auxiliary array to hold the results of the calculation, like this:
int f (int i, int j)
{
if (Dp[i][j] >= 0) return dp[i][j];
if (i = = n-1) return dp[i][j] = a[i][j];
return dp[i][j] = A[i][j] + max (f (i + 1, j), F (i + 1, j + 1));
}
Because A[i][j] may be 0, you need to initialize the DP to-1 in main ():
Memset (DP,-1, sizeof (DP));
Eventually, the program returns the results we want to see:
The complete code for this topic is shown in this article.
PS: For a method of printing a path, see the third part below.