The essence of dynamic programming

     Originally published in:

 

     Let's first look at a problem:

     a, b, c, n are all positive integers, non-negative integers x, y, z satisfy ax + by + cz = n, find min{x + y + z}

     The intuitive algorithm is: after enumerating x, y, z, find min{x + y + z}. However, this is not the best algorithm. After reading this article, you can use dynamic programming to solve this problem.

     

      Before introducing dynamic programming, let's first look at a written test question of T company:

     Those who have studied permutation and combination should be able to do it directly: C(12,5)-C(6,3)*C(6,2)

     The result is: 492

 

     Some friends may have forgotten the permutation and combination, so what should I do? You can consider doing it mechanically. Let's find the law, as shown below:

      Suppose the number of methods from point X to point Y is f(X,Y), then:

      f(M, B) = 1

      f(N, B) = 1

      f(E, B) = f(M, B) = 1

      f(C, B) = f(M, B) +  f(N, B) = 2

      f(D, B) = f(E, B) +  f(C, B) = 3

      

     Taking point B as the origin of (0,0) and a[i][j] as the number of ways to go from point (i,j) to point B, it is easy to get the recurrence formula:

     a[i][j] = a[i][j-1] + a[i-1][j]

     Among them, i and j are both greater than 0. As for the boundary condition that i or j is 0, it is clear at a glance. In addition, note that P is a special point in the figure. At the written test site, if the above recurrence formula is used to make this question, it only takes 3 minutes at most.

 

     When the problem scale becomes larger, it is very troublesome for people to calculate according to the recursive formula, but for computers, it is most suitable for these regular calculations. Next, let the computer calculate:

package main

import "fmt"

func main() {
   a := [6][8]int {}; 
   for j := 1; j < 8; j++ {
       a[0][j] = 1   // first row
   }

   for i := 1; i < 6; i++{
       a[i][0] = 1   // first column
   }

   // B point  a[0][0] = 0
   for i := 1; i < 6; i++ {
       for j := 1; j < 8; j++ {
           a[i][j] = a[i-1][j] + a[i][j-1]
           if i == 2 && j == 4 {
               a[i][j] = 0  // P point
           }
       }
   }

   fmt.Println(a[6-1][8-1]) // A point
}

      The result is: 492

 

     So far, I haven't felt the dynamic programming (Dynamic Programming), so what is dynamic programming? Dynamic programming is the process of solving the optimal decision-making process. It is widely used in economic, military, automation and other fields. The essence of dynamic programming is recursion. However, in some dynamic programming problems, recursion is not obvious, and it takes great effort to build a recurrence relationship.

 

    Finally, let’s look at the question at the beginning of the article. The recursive formula of dynamic programming is: f(n) = min{f(na)+1, f(nb) + 1, f(nc) + 1} , where, f(n) is min{x + y + z} under the scale of n. In addition, attention should be paid to the boundary conditions.

     Dynamic planning is almost a must-test content for written interviews. For job seekers, you need to train more dynamic planning thinking and find feelings. Regarding the content of dynamic programming, let's talk about it first.

Guess you like

Origin blog.csdn.net/stpeace/article/details/108700774