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 }
  • 相关阅读:
    Django + uWSGI + Nginx 实现生产环境部署
    面试题(一)
    Python基础之路
    Tornado之实例和扩展
    Scrapy源码研究前戏
    算法之基本概念
    RedHat6.2系统安装ipvsadm+keepalived
    oracle11G 同时支持IPV4和IPV6配置
    redhat6.5 安装oracle11G
    python解析字体反爬
  • 原文地址:https://www.cnblogs.com/lzy321/p/10431680.html
Copyright © 2011-2022 走看看