zoukankan      html  css  js  c++  java
  • 理解dynamic programming动态规划

    何谓动态规划?

    以菲波那切数列为例,

    1 int fib(int n ){
    2       if(n == 0 || n ==1){
    3            return 1;
    4     }else{
    5            return fib(n - 1) + fib(n - 2);
    6     }    
    7 }

    该递归调用中,有大量重复子集,如图

    在计算fib(5) 的时候,多次计算了fib(2)的值。那为何不在递归搜索的基础上,添加一个小笔记本进行记忆化:只在第一次fib(2)的时候计算结果,而下次再call fib(2)的时候, 可以直接O(1)时间从记事本拿到该结果。

    1  public int fib(int n ){
    2         if( n == 0 || n == 1) return 1;
    3         int [] memo = new int[n + 1]; // 另开一个空间memo记录
    4         Arrays.fill(memo, -1);  //memo上初始值都为-1 
    5         if(memo[n] == -1){  // 若该值没被记录过
    6            memo[n] =  fib(n-1) + fib (n-2); //计算并记录在memo中
    7         }
    8         return memo[n]; //否则,该值不等于defalut的-1 表示已被记录过,直接拿结果
    9     }

    那么,也可以在一个数组中滚动计算出最终memo[n],  这就是DP

    1   public int fib(int n ){
    2         int [] memo = new int[n + 1];
    3         memo[0] = 1;
    4         memo[1] = 1;
    5         for(int i = 2; i <=n; i++){
    6             memo[i] = memo[i-1] + memo[i-2];
    7         }
    8         return memo[n];
    9     }

    总结: 实际上,它们都是递归问题。在很多情况下,用记忆化搜索解出来的答案通常都是能满足需求的。只是动态规划的整个代码会更简洁清晰。也有很多面试官把递归调用时使用记忆化搜索等同于动态规划(top down with memorization is already DP)。当然,条件相同时,动态规划肯定更优。因为记忆化搜索的递归调用中,递归调用需要额外开销。空间角度,使用递归调用需要占用系统的栈空间。 

  • 相关阅读:
    Iphone 启动图的尺寸
    Xcode 7真机测试详解
    android 设置textview中划线效果
    IOS应用在iPhone5和iPhone5s上不能全屏显示,应用画面上下各有1条黑色的解决方案
    配置ant编译时的jdk版本
    mac系统下配置aapt环境变量
    iOS中的2x,3x问题
    Android 字体设置-Typeface讲解
    android:json解析的两个工具:Gson和Jackson的使用小例子
    Android App监听软键盘按键的三种方式
  • 原文地址:https://www.cnblogs.com/liuliu5151/p/9070234.html
Copyright © 2011-2022 走看看