Emperor laugh! A jar of points you

Make it work, make it right, make it fast.   —— Kent Beck

Here the first two sentences say is recursive, that is to say after one iteration. Have to admit recursive Dafa really easy to write, but iterative method is more efficient and fast.

Dynamic programming, may sound strange, but in other words, a recursive come to the preliminary conclusion after write with iterative manner.

Take the classic Fibonacci sequence for instance

    long long fibonacci(int n){

   if(n == 0){ return 1; } else if(n == 1){ return 1; } else{ return fibonacci(n - 1) + fibonacci(n - 2); } }//T(n) = pow(2, n - 1) = O(pow(2, n))
 
      
Copy the code

We accordingly wish to trace recursion:

 We can see in this recursive tree has a lot of duplicate branches, so if we can cut to duplicate branch?

Improved First: Memory of recursive

Copy the code
long long fibonacci(int n){
    long long f[100] = {0};
    if(n == 0){
        return f[0] = 0;
    }
    else if(n == 1){
        return f[1] = 1;
    }
    else if(f[n]){
        return f[n];
    }
    else{
        return f[n] = fibonacci(n - 1) + fibonacci(n - 2);
    }
}//T(n) = pow(2, n - 2) = O(pow(2, n))
Copy the code

 

 

Although deleting duplicate branches, but the complexity does not seem to fall much

Improved II: dynamic programming (non-recursive)

Copy the code
long long fibonacci(int n){
    long long f[100];
    f[0] = 0;
    f[1] = 1;
    for(int i = 2; i <= n; i++){
        f[i] = f[i - 1] + f[i - 2];
    }
    return f[n];
}//T(n) = O(n)
Copy the code

This algorithm change from top to bottom, two above ideas while taking a bottom-up way of thinking, thinking we usually prefer to solve the problem (iteration).

And it should also be photographed I said at the beginning of dynamic programming is to use a recursive come to the preliminary conclusion was converted into the form of iteration.

 

Mentioned dynamic programming, a classic example is:

LCS (Longest Common Subsequence) // longest common subsequence

Sequence: character string is extracted several letters arrayed in the order is extracted from a string

Longest common subsequence: two common subsequence longest

eg: d  i d a c

   a d v a n

  Longest common subsequence: da

Faced with this problem, our conventional thinking is:

1. Identify common subsequence 

2. And then find out where the longest common subsequence

Dynamic programming idea is:

Imagine all the sub-problems into a matrix

 

 

 

Matrix meet:

(1)  if( i == 0 || j == 0 )    A[i][j] = 0

(2)  if( i,j > 0 && Ci == Rj )  A[i][j] = A[i - 1][j - 1] + 1

 

 

(3)  if( i,j > 0 && Ci != Rj )   max( A[i][j - 1], A[i - 1][j] )

 

 

 

 

Copy the code
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <string>
using namespace std;
int main(){
    string str1 = "didac";
    string str2 = "advan";
    int A[7][7] = {0};
    int longest = 0;
    for(int i = 0; i <= str1.length(); i++){
        for(int j = 0; j <= str2.length(); j++){
            if(i == 0 || j == 0){
                A[i][j] = 0;
            }
            else if(i > 0 && j > 0 && str1[i - 1] == str2[j - 1]){
                A[i][j] = A[i - 1][j - 1] + 1;
            }
            else if(i > 0 && j > 0 && str1[i - 1] != str2[j - 1]){
                A[i][j] = max(A[i - 1][j], A[i][j - 1]);
            }
        }
    }
    for(int i = 0; i <= str1.length(); i++){
        for(int j = 0; j <= str2.length(); j++){
            cout << A[i][j];
        }
        cout << endl;
    }

    return 0;
}
Copy the code

Summary: Whether it is from the table view, or from the point of view matrix rule, the length of the common subsequence that is the largest element in the matrix, and the smallest increase in the minimum number of first elements of a common sequence is the element number of columns and rows.

 
Good text to the top 
    long long fibonacci(int n){

   if(n == 0){ return 1; } else if(n == 1){ return 1; } else{ return fibonacci(n - 1) + fibonacci(n - 2); } }//T(n) = pow(2, n - 1) = O(pow(2, n))
 
 
Copy the code

We accordingly wish to trace recursion:

 We can see in this recursive tree has a lot of duplicate branches, so if we can cut to duplicate branch?

Improved First: Memory of recursive

Copy the code
long long fibonacci(int n){
    long long f[100] = {0};
    if(n == 0){
        return f[0] = 0;
    }
    else if(n == 1){
        return f[1] = 1;
    }
    else if(f[n]){
        return f[n];
    }
    else{
        return f[n] = fibonacci(n - 1) + fibonacci(n - 2);
    }
}//T(n) = pow(2, n - 2) = O(pow(2, n))
Copy the code

 

 

Although deleting duplicate branches, but the complexity does not seem to fall much

Improved II: dynamic programming (non-recursive)

Copy the code
long long fibonacci(int n){
    long long f[100];
    f[0] = 0;
    f[1] = 1;
    for(int i = 2; i <= n; i++){
        f[i] = f[i - 1] + f[i - 2];
    }
    return f[n];
}//T(n) = O(n)
Copy the code

This algorithm change from top to bottom, two above ideas while taking a bottom-up way of thinking, thinking we usually prefer to solve the problem (iteration).

And it should also be photographed I said at the beginning of dynamic programming is to use a recursive come to the preliminary conclusion was converted into the form of iteration.

 

Mentioned dynamic programming, a classic example is:

LCS (Longest Common Subsequence) // longest common subsequence

Sequence: character string is extracted several letters arrayed in the order is extracted from a string

Longest common subsequence: two common subsequence longest

eg: d  i d a c

   a d v a n

  Longest common subsequence: da

Faced with this problem, our conventional thinking is:

1. Identify common subsequence 

2. And then find out where the longest common subsequence

Dynamic programming idea is:

Imagine all the sub-problems into a matrix

 

 

 

Matrix meet:

(1)  if( i == 0 || j == 0 )    A[i][j] = 0

(2)  if( i,j > 0 && Ci == Rj )  A[i][j] = A[i - 1][j - 1] + 1

 

 

(3)  if( i,j > 0 && Ci != Rj )   max( A[i][j - 1], A[i - 1][j] )

 

 

 

 

Copy the code
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <string>
using namespace std;
int main(){
    string str1 = "didac";
    string str2 = "advan";
    int A[7][7] = {0};
    int longest = 0;
    for(int i = 0; i <= str1.length(); i++){
        for(int j = 0; j <= str2.length(); j++){
            if(i == 0 || j == 0){
                A[i][j] = 0;
            }
            else if(i > 0 && j > 0 && str1[i - 1] == str2[j - 1]){
                A[i][j] = A[i - 1][j - 1] + 1;
            }
            else if(i > 0 && j > 0 && str1[i - 1] != str2[j - 1]){
                A[i][j] = max(A[i - 1][j], A[i][j - 1]);
            }
        }
    }
    for(int i = 0; i <= str1.length(); i++){
        for(int j = 0; j <= str2.length(); j++){
            cout << A[i][j];
        }
        cout << endl;
    }

    return 0;
}
Copy the code

Summary: Whether it is from the table view, or from the point of view matrix rule, the length of the common subsequence that is the largest element in the matrix, and the smallest increase in the minimum number of first elements of a common sequence is the element number of columns and rows.

Guess you like

Origin www.cnblogs.com/qwerqwer1234/p/12532175.html