Dynamic planning law summary

Public method reproduced in numbers:

First, the three steps of dynamic programming

Dynamic programming, is nothing more than the use of history to avoid repeating our calculations. These historical record , we have to take some variables to hold, usually with a one-dimensional array or two-dimensional array to store. Below us to do in terms of dynamic programming problems under three very important step,

The first step : Define the meaning of the array elements , it says, we will use an array to hold the history array, assuming a one-dimensional array dp [] it. This time there is a very, very important point is that the meaning of the provisions of the array elements you, such as your dp [i] is what does it mean?

Second step : find out the relationship between the array elements , I think the dynamic programming, or a little similar to when our high school induction , and when we have to calculate dp [n], can use dp [n- 1], dp [n-2 ] ... ..dp [1], to launch dp [n], that is, you can use historical data to introduce new elements of value, so we have to find out the relationship between the array elements , e.g. dp [n] = dp [n -1] + dp [n-2], this is the type of their relationship. This step is the hardest step behind I speak for several types of questions.

Learned of dynamic programming may have often heard optimal substructure , to split a big problem into smaller problems, time to say, the very beginning, I was right optimal substructure a dream ignorant of force. Guess you also hear a lot, so this time, I will put it another form of speaking, it is no longer a variety of sub-problems, various optimal substructure . So Gangster Do not spray me again Luanjiang, as I said, this is what I do question their usual routine.

The third step : to find out the initial value . Learned mathematical induction knows, although we know the relationship between the array elements, e.g. dp [n] = dp [n -1] + dp [n-2], we can dp [n-1] and dp [n-2] to compute dp [n], however, we must know the initial value ah, for example, has been pushed down, then, will the dp [3] = dp [2 ] + dp [1]. The dp [2] and dp [1] is no longer decomposed, so we must be able to directly obtain dp [2] and the value dp [1], which is the so-called initial value .

Of the initial value , and with the relationship between the array elements , then we can get dp [n] value, while dp [n] meaning is up to you to define, and you want to ask anything, by definition What it is , so that the solution of this question will come out.

Do not understand? All right, let's look thirty-four example , I speak in strict accordance with the steps to explain to everyone.

Second, Case Detailed

Case 1, a simple one-dimensional DP

Problem Description: A frog can jump on a Class 1 level, you can also hop on level 2. The frog jumped seeking a total of n grade level how many jumps.

Meaning (1), the definition of array elements

As I said above steps, first of all let's define the meaning dp [i], our problem is to ask the frog jumped on stage n steps by a total of how many jumps, then we define dp [i] meaning is: i jumped a grade level total dp [i] kind of jumps . Thus, if we can calculate dp [n], the answer is not that we ask for it? So the first step defined.

(2) to identify the relationship between array elements

Our aim is to require dp [n], dynamic programming problem, as you often hear it, is to a scale larger problem into several scale is relatively small problems, big problems then deduced by a small problem . In other words, dp [n] size is n, the size of which is smaller than n-1, n-2, n-3 .... In other words, dp [n] will and dp [n-1], dp [n-2] .... the existence of a relationship. We want to find out their relationship.

So the question is, how to find?

How to find this, is one of the hardest core , we must go back to the question itself, to find their relationship, dp [n] is equal to what exactly would it?

For this question, as the case may choose a jump, jump two may be selected, so the frog reaches stage n steps in two ways

One is to jump from the first-stage n-1

One is from the jump to stage n-2

Because we want to count all of the possible jumps , so there dp [n] = dp [n -1] + dp [n-2].

(3) identify the initial conditions

When n = 1, dp [1] = dp [0] + dp [-1], but we are not allowed to be an array index is negative, so for dp [1], we have to be given its direct value , corresponding to the initial value, obviously, dp [1] = 1. Like, dp [0] = 0. (as 0 level, it is certainly 0 kinds of jumps). Thus obtained Initial value:

DP [0] = of 0. The
DP [. 1] = 1.
That When n <= 1, dp [n] = n.

Are three steps to do it, then we have to write the code bar, code detailed notes drops.

int F ( int n-) {
     IF (n-<=. 1 )
     return n-;
     // create an array to hold historical data 
    int [] DP = new new  int [n-+. 1 ];
     // initial value is given 
    dp [0] = 0 ;
    DP [ . 1] =. 1 ;
     // calculated by the relational expression DP [n-] 
    for ( int I = 2; I <= n-; I ++ ) {
        dp[i] = dp[i-1] + dp[i-2];
    }
    // The final result is returned 
    return DP [n-];
}
(4), say initialization

First think of the following, do you think, there is no problem with the above code?

A problem is, right or wrong, wrong in looking for the initial value is not precise enough , which is why I get so deliberately intended to tell you about the rigor of the initial value . For example, the above problem, when n = 2, dp [2] = dp [1] + dp [0] = 1. This is clearly wrong, you can simulate it, you should be dp [2] = 2. In other words, looking at the initial value, you must be careful not to find a leak, dp [2] can be considered an initial value, a formula can not be calculated. Some might say, I can not think of how to do? This very good run, do a few questions on it.

--------------------------------------

Below I will list three different examples, and then in a future article, I will continue to follow this step, for everyone to find a few more difficult and different types of questions. Below these few examples, I do not speak in detail the characteristics of Kazakhstan. In fact, the above one-dimensional array that can optimize the space into smaller, but now we do not speak to optimize things, the following question is, do not speak optimized version.

Case II: DP two-dimensional array

I had dozens of questions DP algorithm, we can say that 80% of the title, is to use two-dimensional array, so the following questions mainly two-dimensional array-based, of course, some might say, to use a one-dimensional or two-dimensional, how do I know? This is OK, then read on.

Problem Description

A robot located in a left corner mxn grid (starting point figure below labeled "Start").

The robot can only move one step to the right or down. Robot trying to reach the bottom right corner of the grid (in the following figure labeled "Finish").

Q. How many different paths there are in total?

 

This is leetcode of 62 questions: https: //leetcode-cn.com/problems/unique-paths/

Still the same, three steps to resolve.

Meaning a step, defined array elements

Since our goal is from left to bottom right path there are a number of species, then we define dp [i] [j] meaning is: when the robot came from the upper left corner (i, j) in this position, a total of dp [i] [j] species path . So, dp [m-1] [ n-1] is that we want to answer.

Note that this is equivalent to a two-dimensional grid array, the array is an index from 0 to start counting, so the position of the lower right corner is (m-1, n - 1), so dp [m-1] [n- 1] we are looking for answers.

Step two: Find the relationship between array elements relationship

Imagine the following, how can the robot to reach the (i, j) in this position? Since the robot can go down or go to the right, so there are two ways to reach

One is to go from the (i-1, j) reaches the position of the step

One is from (i, j - 1) take the step to reach this position

Since the step of calculating all possible, it is possible to go all the paths are combined, so the relationship is dp [i] [j] = dp [i-1] [j] + dp [i] [j-1 ].

Step three, find out the initial value

Obviously, when dp [i] [j], if there is a i or j is 0, then the relationship can use it? Answer is impossible, because this time the i - 1 or j - 1, becomes negative, the array will be a problem, so our initial value is calculated for all the dp [0] [0 ... .n- 1] and all dp [0 ... .m-1] [0]. This is very easy to calculate, corresponds to the uppermost row in FIG computer and a left side. So the initial values ​​are as follows:

dp [0] [0 ... .n-1] = 1; // equivalent to the top line, the robot can only have been left to go

dp [0 ... m-1] [0] = 1; // corresponds to the leftmost one robot can only go straight down

Line and Code

Step three written down directly look at the code

public static int uniquePaths(int m, int n) {
    if (m <= 0 || n <= 0) {
        return 0;
    }

    int[][] dp = new int[m][n]; // 
      // 初始化
      for(int i = 0; i < m; i++){
      dp[i][0] = 1;
    }
      for(int i = 0; i < n; i++){
      dp[0][i] = 1;
    }
        // 推导出 dp[m-1][n-1]
    for (int i = 1; i < m; i++) {
        for (int j = 1; j < n; j++) {
            dp[i][j] = dp[i-1][j] + dp[i][j-1];
        }
    }
    return dp[m-1][n-1];

O (n * m) can optimize the spatial complexity to O space (min (n, m)) of complexity, but to speak here.

Case III, a two-dimensional array of DP

I write to you, a little tired ,, but still have to write down, so to see the small partner, you may have to continue to behold. Below this question is not difficult, than the above Diudiu a difficult, but also very similar

Problem Description

Given a non-negative integer  m  X  n-  grid, find a path from left to bottom right, so that the sum of the minimum number of paths.

Note: you can only move one step down or to the right.

For example:
Input:
arr = [
  [1,3,1],
  [1,5,1],
  [4,2,1]
]
Output: 7 
explained: since the path the sum of 1 → 3 → 1 → 1 → 1 minimum.

And above similar, but is considered optimal path and this is leetcode 64th title: https: //leetcode-cn.com/problems/minimum-path-sum/

Still the same, some people are tired of, ha ha, but I still have to follow the steps to write, let those deepen understanding not understand. One might think that these questions are too simple right, do not panic, white first entry, these are medium-level, behind a few hard levels.

Meaning a step, defined array elements

Since our goal is from top left to bottom right path and is the smallest number, then we define dp [i] [j] meaning is: when the robot came from the upper left corner (i, j) in this position, most and the path is DP [I] [J] . So, dp [m-1] [ n-1] is that we want to answer.

Note that this is equivalent to a two-dimensional grid array, the array index is from 0 to start counting, the position of the lower corner of the (m-1, n - 1), so dp [m-1] [n- 1] is that we go out.

Step two: Find the relationship between array elements relationship

Imagine the following, how can the robot to reach the (i, j) in this position? Since the robot can go down or go to the right, so there are two ways to reach

One is to go from the (i-1, j) reaches the position of the step

One is from (i, j - 1) take the step to reach this position

But this time instead of calculating all possible paths, but calculated path and which is the smallest , so we need these two methods, select one of such value dp [i] [j] is the smallest, apparently

DP [I] [J] = min (DP [. 1-I] [J], DP [I] [J-. 1]) + ARR [I] [J]; // ARR [I] [J] indicates that the network the value of cell types
Step three, find out the initial value

Obviously, when dp [i] [j], if there is a i or j is 0, then the relationship can use it? Answer is impossible, because this time the i - 1 or j - 1, becomes negative, the array will be a problem, so our initial value is calculated for all the dp [0] [0 ... .n- 1] and all dp [0 ... .m-1] [0]. This is very easy to calculate, corresponds to the uppermost row in FIG computer and a left side. So the initial values ​​are as follows:

dp [0] [j] = arr [0] [j] + dp [0] [j-1]; // corresponds to the top line, the robot has only go left

dp [i] [0] = arr [i] [0] + dp [i] [0]; // corresponds to the leftmost one robot can only go straight down

code show as below
public static int uniquePaths(int[][] arr) {
      int m = arr.length;
      int n = arr[0].length;
    if (m <= 0 || n <= 0) {
        return 0;
    }

    int [] [] DP = new new  int [m] [n-]; //  
      // initialize 
      DP [0] [0] = ARR [0] [0 ];
       // initialize the leftmost column 
      for ( int I =. 1 ; I <m; I ++ ) {
      dp[i][0] = dp[i-1][0] + arr[i][0];
    }
      // initialize the uppermost row 
      for ( int I =. 1; I <n-; I ++ ) {
      dp[0][i] = dp[0][i-1] + arr[0][i];
    }
        // 推导出 dp[m-1][n-1]
    for (int i = 1; i < m; i++) {
        for (int j = 1; j < n; j++) {
            dp[i][j] = Math.min(dp[i-1][j], dp[i][j-1]) + arr[i][j];
        }
    }
    return dp[m-1][n-1];
}

O (n * m) can optimize the spatial complexity to O space (min (n, m)) of complexity, but to speak here. More original algorithm article, we can focus on my public number "hard to force the farming code."

Case 4: Edit this distance did not understand back then look! ! !

This question is this to the harder than the above, positioned leetcdoe is hard level. It seems to be leetcode No. 72 questions.

Problem Description

Given two words word1 and word2, word1 to calculate the minimum number of converting operations word2 used.

You can perform the following three operations on one word:

Insert a character
delete a character
to replace a character

Example 1 :
Input: word1 = "Horse", word2 = "ROS" 
Output: 3
Explanation: 
Horse -> rorse (the 'h' is replaced with 'R & lt' )
rorse -> Rose (delete 'R & lt' )
Rose -> ROS (Delete 'e')

answer

Still the same, to follow the three steps above, and I am here to tell you that 90 percent of string problems can be solved using dynamic programming, and 90% is a two-dimensional array.

Meaning a step, defined array elements

Since our aim to find the minimum number of converting operations word1 word2 used. Then we define dp [i] [j] is the meaning: when the length of the string word1 is i, the length of the string word2 j, the minimum operation frequency and converted to word1 word2 used is dp [i] [ J] .

Sometimes, meaning the array is not easy to find, so then again, I'll give you a routine, and the rest you have to see to understand.

Step two: Find the relationship between array elements relationship

Then we are looking dp relationship between [i] [j] elements, compared to the other questions, this question is relatively difficult to find it, but, no matter how hard to find, in most cases, dp [i] [j] and dp [i-1] [j ], dp [i] [j-1], dp [i-1] [j-1] is certainly a relationship exists. Because our goal is, from a small scale, through a number of operations, large-scale deduced . For this question, we can perform three operations on word1

Insert a character
delete a character
to replace a character

Since the minimum number of operations we want, so we have to look for best practices. Then there is the following relationship:

First, if we word1 [i] and word2 [j] equal, no action is required at this time, there is clearly dp [i] [j] = dp [i-1] [j-1]. (Remember meaning dp [i] [j] ha).

Second, if we word1 [i] and word2 [j] are not equal, this time we have to adjust, and adjust the operation of three kinds, we have to choose a. Relationship between the following three operations corresponding to the test (note the difference character string):

(1), if the character word1 [i] is replaced with word2 [j] equal, there dp [i] [j] = dp [i-1] [j-1] + 1;

(2) if an insert with word2 [j] is equal to the end of the character string word1, there dp [i] [j] = dp [i] [j-1] + 1;

(3), if the character word1 [i] is deleted, there dp [i] [j] = dp [i-1] [j] + 1;

Then we should select an action, such that dp [i] [j] is a minimum value, clearly

dp[i] [j] = min(dp[i-1] [j-1],dp[i] [j-1],dp[[i-1] [j]]) + 1;

So, our relationship to launch it,

Step three, find out the initial value

Obviously, when dp [i] [j], if there is a i or j is 0, then the relationship can use it? Answer is impossible, because this time the i - 1 or j - 1, becomes negative, the array will be a problem, so our initial value is calculated for all the dp [0] [0 ... .n] and all dp [0 ... .m] [0]. This is very easy to calculate, because when there is a string of length 0 is transformed into another character string, it will only have the insert and delete operations.

Code is as follows (may slide around)
public int minDistance(String word1, String word2) {
    int n1 = word1.length();
    int n2 = word2.length();
    int[][] dp = new int[n1 + 1][n2 + 1];
    // dp[0][0...n2]的初始值
    for (int j = 1; j <= n2; j++) 
        DP [ 0] [J] DP = [0] [J -. 1] +. 1 ;
     // DP [N1 ... 0] [0] is the initial value 
    for ( int I =. 1; I <= N1; I ++) DP [I] [0] = DP [I -. 1] [0] +. 1 ;
         // by the equation Release DP [N1] [N2] 
    for ( int I =. 1; I <= N1; I ++ ) {
         for ( int . 1 = J; J <= N2; J ++ ) {
               // If word1 [i] and word2 [j] equal. Corresponding to the i-th character subscripts. 1-i 
            IF (word1.charAt (i -. 1) == word2.charAt (J -. 1 )) {
                p[i][j] = dp[i - 1][j - 1];
            }else {
               dp[i][j] = Math.min(Math.min(dp[i - 1][j - 1], dp[i][j - 1]), dp[i - 1][j]) + 1;
            }         
        }
    }
    return dp[n1][n2];  
}

Finally said, if you want to practice, you can go leetcode, select the dynamic programming topics, then continuous brush dozens ensure that you will never afraid of the dynamic programming. Of course, encountered difficult, we still have to hang.

Leetcode dynamic programming directly to: https: //leetcode-cn.com/tag/dynamic-programming/

More algorithms original article, I can focus on the public number " hard to force the farming code ."

Third, the summary

The above problems are basically not very difficult entry title, but the last relatively little difficult, was supposed to write a few little difficult, and talking about how to optimize , but looked under the words, the article a little longer, about how to optimize and revisit it later, after the article, I will follow this step in to tell you forty-five dynamic programming  hard  level questions, the text will be placed on the second day to push for everyone to learn. If you're interested in the article to see more people, then the optimization articles will soon be out of line and, though very few people are interested in it, power is relatively small, probably will be slower, so you small partners, if they feel rewarding, You may wish to triple to go up, hee hee. 

 

Guess you like

Origin www.cnblogs.com/doyi111/p/11865609.html