zoukankan      html  css  js  c++  java
  • 算法:动态规划入门

    基本内容:

    这几天学习了一下动态规划,特此整理。

    在一道题中反复使用或者反复计算,将重复的内容存到一个集合里面,计算后面的时候直接从集合里面取值,可以大幅优化时间和空间。

    核心:记住求过的解来节省时间。

    例:

    计算:1+1+1+1+1

    结果 不使用动态规划加五次得到 5

    计算:给上面式子加一

    结果:使用动态规划:计算过程为取上面结果,给结果加1,只进行一次计算。(很快就能计算出来)

    动态规划有两种形式:

    1.自顶向下的备忘录法(空间复杂度高)

    2.自底向上(推荐)

    为了说明两种方法:举一个简单例子:

    斐波那契数列:1 1 2 3 5 8 13 ...........

    Fibonacci(n)  =  1;  n  =  0;

    Fibonacci(n)  =  1;  n  =  1;

    Fibonacci(n)  =  1;  n  = Fibonacci(n-1)  +  Fibonacci(n-2) ;

    自顶向下(递归):

     1 public class DP{
     2     public static int f(int n){
     3         if(n==0){
     4             return 1;
     5         }
     6          if(n==1){
     7             return 1;
     8          }
     9         return f(n-1)+f(n-2);
    10     }
    11     public static void main(String args[]){
    12            int n=5;
    13             f(n);
    14     }
    15 }

    这个复杂度是一个树形结构,十分复杂,O(2^n)

    如果将f(0),f(1),f(2).......存入表中,如果计算时,算过就从表中直接取.

    自顶向下(递归)动态规划(备忘录法)(因为使用了递归,所以空间复杂度较高)

    简单来说就是使用一个数组或者集合或者其他,将已经计算过的值存在里面,计算的时候,先查看这个位置的值有没有被计算过,有就返回,没有就计算。

    这里的数组就相当于一个备忘录

     1 public class DP{
     2     public static void main(String args[]){
     3                 int n=5;
     4                 int[] bak=new int[n+1];
     5                 for(int i=0;i<n+1;i++){
     6                     bak[i]=-1;
     7                 }
     8                 System.out. println(f(n,bak));
     9             }
    10     public static int f(int n,int[] bak){
    11         if(n==0){
    12             return 1;
    13         }
    14         if(n==1){
    15             return 1;
    16         }
    17         if(bak[n] !=-1){
    18             return bak[n];
    19         }
    20         int result =f(n-1,bak)+f(n-2,bak);
    21         bak[n]=result;
    22         return result;
    23     }
    24 
    25 }

     自底向上:

    就是说不使用数组,使用两个值r1,r2,代表r1,r2,从最开始向目标计算

     1 public class Main{
     2     public static void main(String args[]){
     3         int n=5;
     4         System.out. println(f(n));
     5     }
     6     public static int f(int n){
     7         if(n==0){
     8             return 1;
     9         }
    10         if(n==1){
    11             return 1;
    12         }
    13         int result = 0;
    14         int r1=1;
    15         int r2=1;
    16         for(int i=2;i<=n;i++){
    17             result= r1 + r2;
    18             r1=r2;
    19             r2=result;
    20         }
    21         return result;
    22     }
    23 
    24 }
  • 相关阅读:
    2. Add Two Numbers
    1. Two Sum
    22. Generate Parentheses (backTracking)
    21. Merge Two Sorted Lists
    20. Valid Parentheses (Stack)
    19. Remove Nth Node From End of List
    18. 4Sum (通用算法 nSum)
    17. Letter Combinations of a Phone Number (backtracking)
    LeetCode SQL: Combine Two Tables
    LeetCode SQL:Employees Earning More Than Their Managers
  • 原文地址:https://www.cnblogs.com/lzy321/p/10431680.html
Copyright © 2011-2022 走看看