Algorithms talk about dynamic programming problems

Classic dynamic programming problem (Fibonacci sequence)

Use the dynamic programming algorithm to implement the Fibonacci sequence (time complexity O(n)), and use the exhaustive method to implement the Fibonacci sequence (time complexity O(2^n))

How to implement the Fibonacci sequence using dynamic programming?

Algorithm idea:

When we solve the Fibonacci sequence, the first thing that comes to our mind is of course to use the recursive method! But let's think about a problem, if we ask to solve Fb(6) 


We can see that for the number on the right, we have already obtained it on the left. When using the recursive algorithm, the number on the right is recalculated and the complexity is multiplied by 2, so the time complexity of the calculation is O(2^ n). Just imagine if we store the previously calculated numbers in an array, will the time complexity increase? The answer is obvious. This leads to an important concept of dynamic programming: optimal substructure. We divide the solution of the problem into the optimal solution of the sub-problem, and then solve it by the optimal solution of the sub-problem. But how is the previous solution effective for finding the overall optimal solution? We lead to the second important feature of dynamic programming: the overlapping of subproblems. The overlap of sub-problems is an important condition for whether dynamic programming can be used, because dynamic programming is essentially an algorithm that exchanges time for space. We need to open up a space in memory to store the solutions of its sub-problems, so that when there is overlap in the future, use. So how do we ensure that the solutions we record are valid? This leads to the third concept of dynamic programming: no aftereffects. We must ensure that each state (solution) is a complete summary of the past, so that future use of this state will not affect subsequent computations.

Talk is cheap,let’s show code

 

 

// brute force algorithm (recursive)

public static int Fb(int n){

       if(n==1||n==2){

           return 1;

       }else{

           returnFb(n-1)+Fb(n-2);

       }

    }

 

 

//Algorithm for dynamic programming (exchange space for time)

public static int[] dpFb(int n){

       int a[]=new int[n];

       a[0]=1;

       a[1]=1;

       for(int i=2;i<n;i++){

           a[i]=a[i-1]+a[i-2];

       }

       return a;

    }

Let's solve another problem of dynamic programming: the problem of the longest subsequence

Let's first understand what a subsequence is

There are strings X=<x1,x2,x3...xm>

For the string Z=<z1,z2,z3...zk>

If there is a strictly increasing sequence generated by the elements of X (must be strictly increasing, select the one that can be spaced)

Zj=xi    i=1,2….k

Then we call Z a subsequence of X.

For two string sequences:

X=<x1,x2,x3...xm>               the first string

Y=<y1, y2, y3...yn>                the second string

A sequence that is both a subsequence of X and a subsequence of Y is called their common subsequence

 

 

Algorithm idea:

There are two algorithms for finding the largest subsequence (the first: brute force algorithm; the second: dynamic programming algorithm). Let's discuss them one by one:

Brute force algorithm :

Might as well set |m|<|n|, then we start to extract elements from the set of X to generate subsequences, there are a total of 2^m subsequences, and then scan in the set of Y, scanning n elements at a time, a total of To scan 2^m times, the time complexity is O(n*2^m)

dynamic programming algorithm


The yellow border in the figure represents the solution to the final problem we need to solve, and the red border in the figure is our optimal substructure

Let's discuss different sub-problems (here we design a problem of choosing and not choosing, this idea is very important in the idea of ​​dynamic programming, similar to the piecewise function in mathematics)

1 、若 xm = in,

Z(k-1) is the LCS of X(m-1) and Y(n-1)

2. If xm yn, do not consider xm to enter the common subsequence, that is, xm zk;

Z is the LCS of X(m-1) and Y(n)

3. If xm yn, consider xm to enter the common subsequence, that is, yn=zk;

Z is the LCS of X(m) and Y(n)

The recurrence equation of the optimization function:

 

Talk is cheap,let’s show code

Dynamic Programming Algorithms::

public class dp {

 

    public static int f(String str1,String str2){

       char a[]=str1.toCharArray();

       char b[]=str2.toCharArray();

       int c[][]=newint [a.length][b.length];

       int max=0;

       for(int i=1;i<c.length;i++){

           for(int j=1;j<c[i].length;j++){

              if(a[i-1]==b[j-1]){

                  c[i][j]=c[i-1][j-1]+1;

                  if(c[i][j]>max){

                     max=c[i][j];

                  }

              }

           }

       }

       return max;

    }

    public static void main(String[] args){

       int n = f("abcdkkk", "baabcdadabc");

       System.out.println(n);

    }

}

 



Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325688474&siteId=291194637