Front end programmer learn algorithm series (x) dynamic programming

Time:2020-11-26

The overall idea of dynamic programming is to solve recursive problems, and then optimize a large number of overlapping subproblems in the recursive process. The top-down solution is memory search, and the bottom-up solution is dynamic programming. The top-down solution is usually better understood. After we understand it, we change it to bottom-up dynamic programming;

Offer 10 – I. Fibonacci series
Write a function, input n, and find the nth term of Fibonacci sequence. Fibonacci sequence is defined as follows:

F(0) = 0, F(1) = 1
F (n) = f (n – 1) + F (n – 2), where n > 1
The Fibonacci number sequence starts with 0 and 1, and the subsequent Fibonacci number is obtained by adding the previous two numbers.

The answer needs to take the module 1e9 + 7 (100000007). If the initial calculation result is: 100000008, please return 1.

Example 1:

Input: n = 2
Output: 1
Example 2:

Input: 5
Output: 5

1. Fibonacci’s idea is that the solution of FIB (n) is transformed into FIB (n-1) + FIB (n-2). FIB (n-1) can be transformed into FIB (n-1-1) + FIB (N-2-1). With the recursion, we will finally get n = 1 and N = 0. At the same time, we know that when n = 0, FIB (0) is equal to 0, FIB (1) is equal to 1,

/**
 * @param {number} n
 * @return {number}
 */
var fib = function(n) {
    if(n==0){
      return 0 
    }
    if(n==1){
       return 1
    }
    return fib(n-1) +fib(n-2)
};

 

2. The above code implements a Fibonacci sequence, but the time complexity of Fibonacci sequence is o to the nth power, because there are a lot of repeated solutions when we solve. On the basis of the above, we use cache to cache the calculation results. If cache [n] exists, directly solve the problem to prevent repeated calculation,

/**
 * @param {number} n
 * @return {number}
 */
var fib = function(n) { 
    const cache = {
        0:0n,
        1:1n,
    };
    return Fibonacci(n) % 1000000007n;
    function Fibonacci(n){
        if(cache[n]!==undefined) {
            return cache[n]
        }
        cache[n] = Fibonacci(n - 1) + Fibonacci(n - 2)
        return cache[n];
    }
    
};

3. We transform it into a dynamic programming solution, from bottom to top. Fibonacci = 0, Fibonacci = 0, Fibonacci = 1, Fibonacci [2] = Fibonacci [2-1] + Fibonacci [2-2], we only need the solution Fibonacci [n] when Fibonacci = 0

/**
 * @param {number} n
 * @return {number}
 */
var fib = function(n) {
    let fibonacci = [0,1];
    for(let i = 2; i <= n; i ++) {
        fibonacci[i] = (fibonacci[i - 1] + fibonacci[i - 2]) % (1e9 +7);
    }
    return fibonacci[n];

};

Let’s look at a typical Fibonacci problem

70. Climbing stairs
Suppose you’re climbing stairs. It takes n steps for you to get to the top of the building.

You can climb one or two steps at a time. How many different ways can you climb to the top of a building?

Note: given n is a positive integer.

Example 1:

Input: 2
Output: 2
Explanation: there are two ways to get to the top of a building.
1. Order 1 + order 1
2. 2 steps

Problem solving: this problem is the same as the previous one, so we won’t explain it in depth. We can use objects or arrays when using memory results
1. Top down solution

/**
 * @param {number} n
 * @return {number}
 */
var climbStairs = function (n,map={1:1,2:2}) {
    if (map[n]) return map[n];
    else map[n]=map[n-1]+map[n-2];
    return climbStairs(n - 1,map) + climbStairs(n - 2,map);
};

2. Bottom up solution

/**
 * @param {number} n
 * @return {number}
 */
var climbStairs = function (n) {
      let catche = [1,1]
      for(let i=2;i<=n;i++){
         catche[i] = catche[i-1] +catche[i-2] 
      }
      return catche[n]
};

343. Integer split
Given a positive integer n, divide it into the sum of at least two positive integers and maximize the product of these integers. Returns the maximum product you can get.

Example 1:

Input: 2
Output: 1
Explanation: 2 = 1 + 1, 1 × 1 = 1.
Example 2:

Input: 10
Output: 36
Interpretation: 10 = 3 + 3 + 4, 3 × 3 × 4 = 36.

Problem solving:

1. In order to obtain the maximum product obtained by dividing n, we need to find the maximum result of dividing n into 1 and n-1, 2 and n-2 into the maximum score of n-1 and 1, and take the maximum value in this result,
2. Each time n can select the current value, or I * (n-i) is not segmenting n, and I * continue to split the result of n-i I * D (n-i)

3. We define the result of the maximum value of N in DP object to avoid repeated solution

/**
 * @param {number} n
 * @return {number}
 */
var integerBreak = function(n) {
     //Defines the maximum value of N solved by the DP cache 
     const dp = {}
     function d(n){
          if(n==1){
             return 1
          }
          if(dp[n]!==undefined){
               return dp[n]
          }
          let res = -1
          for(let i =1;i

Problem solving 2

The state array DP [i] represents that the number I is split into the maximum product of the sum of at least two positive integers. For convenience of calculation, the length of DP is n + 1 and the value is initialized to 1.

Obviously, DP [2] is equal to 1, and the outer loop traverses from 3 until n stops. The inner loop J starts from 1 and stops before I. it represents that the number I can be split into j + (I – J). However, J * (I – J) is not necessarily the maximum product, because I-J is not necessarily greater than DP [I – J] (the maximum product of the sum of integers divided by the number I-J), the maximum value should be selected as the result of DP [i].

The space complexity is O (n) O (n), and the time complexity is O (n ^ 2) O (n)

/**
 * @param {number} n
 * @return {number}
 */
var integerBreak = function(n) {

    const dp = new Array(n + 1).fill(1);
    for (let i = 3; i <= n; ++i) {
        for (let j = 1; j < i; ++j) {
            //Each attempt splits n into the value of j + (I-J)
            dp[i] = Math.max(dp[i], j * (i - j), j * dp[i - j]);
        }
    }
    return dp[n];

};

 

198
You are a professional thief, planning to steal houses along the street. There is a certain amount of cash hidden in each room. The only restriction factor affecting your theft is that the adjacent houses are equipped with interconnected anti-theft system. If two adjacent houses are broken in by thieves at the same night, the system will automatically alarm.

Given an array of non negative integers representing the amount of money stored in each house, calculate the maximum amount of money you can steal overnight without triggering the alarm.

Example 1:

Input: [1,2,3,1]
Output: 4
Explanation: steal house 1 (amount = 1), then steal house 3 (amount = 3).
The maximum amount stolen = 1 + 3 = 4.

Problem solving:

1. For a room, we can choose to steal or not to steal. If we steal, we will choose the room with N + 2 to try to steal, and the maximum value will be taken

2. The value we solve is the maximum value, res, which does not consider stealing the current room and considering stealing the current room= Math.max (RES, nums [i] + room (nums, I + 2)), because I + 2 may be out of bounds, so when nums.length When < = index, we directly return 0

3. We use tests to store whether the room has been stolen. If tests has accessed the room, it will return the value directly. If not, we will store the value of N solved in tests

/**
 * @param {number[]} nums
 * @return {number}
 */
var rob = function(nums) {
     let tests = new Array(nums.length).fill(-1)
     
     function room(nums,index){
         if(nums.length<=index){
             return 0
         }
         if(tests[index]!==-1){
            return tests[index]
         }
         let res = 0
         for(let i =index;i

Solution 2

Dynamic programming equation: DP [n] = max (DP [n-1], DP [n-2] + Num)
Because it is not allowed to break into the adjacent houses, the maximum value of N house can be stolen at the current position, either the maximum value of n-1 house can be stolen, or the maximum value of n-2 house can be stolen plus the current house value, and the maximum value between the two is taken
For example, if the maximum theft value of room 1 is 33, that is, DP [1] = 3; if the maximum value of room 2 is 44, that is, DP [2] = 4; if the value of room 3 is 22, that is num = 2, then DP [3] = max (DP [2], DP [1] + Num) = max (4, 3 + 2) = 5, and the maximum theft value of room 3 is 55
Time complexity: O (n) O (n), NN is array length

/**
 * @param {number[]} nums
 * @return {number}
 */
var rob = function(nums) {
    const len = nums.length;
    if(len == 0)
        return 0;
    const dp = new Array(len + 1);
    dp[0] = 0;
    dp[1] = nums[0];
    for(let i = 2; i <= len; i++) {
        dp[i] = Math.max(dp[i-1], dp[i-2] + nums[i-1]);
    }
    return dp[len];
};