动态规划初识(爬楼梯问题)

1.什么是动态规划

   自己的理解就是搜索问题的优化,可以用动归解决的问题都可以用搜索(DFS)来做

2. 动态规划问题的分类

   1.Maxtrix DP 坐标类型的动归(求路径,最大,最小)

   2 Sequence DP 序列的动归

   3 TWO Sequences DP 双序列的动归问题

   4 背包问题

 

3  动态规划的要点

    1.state 状态 f[i] 标识前i个位置/数字/字母

    2.function f[i]=f[j]  j是i之前的位置,也叫状态转移方程

   3. 初始化f[0]

   4. 答案是什么 answer f[i-1]

 

 

例题 爬楼梯问题

假设你正在爬楼梯,需要n步你才能到达顶部。但每次你只能爬一步或者两步,你能有多少种不同的方法爬到楼顶部?

比如n=3,1+1+1=1+2=2+1=3,共有3中不同的方法   返回 3

 

分析 按照上面的要点分析

1  f[i] 标识前爬到i层有多少种方式

2  f[i] 的状态方程,由于只能爬一或者两步  f[i] 是从f[i-2] 或者f[i-1] 来的 f[i] = f[i-1]+f[i-2]

3  初始化状态 f[0] = 1 f[1]=2  f[0]表示前1级台阶的方案数目,f[1] 标识前2级的方案数目

4 answer f[i-1]

 

分析后 代码就简单了

 public int climbStairs(int n) {
         int[] f =new int[n];
        if (n<=1){
            return 1;
        }

        if(n==2){
            return 2;
        }

        f[0]=1;
        f[1]=2;
        if(n<=2){
            return f[n];
        }

        for(int i=2;i<=n-1;i++){
            f[i]=f[i-1]+f[i-2];
        }
        return f[n-1];
    }

  

   动归和搜索的对比

    完成 时间复杂度为O(n)

   这题当然可以用dfs搜索来做

   搜索的方式存在大量的重复计算,如下,例如 dfs(99)=dfs(98)+dfs(97)  dfs(98)=dfs(97)+dfs(96) 其实dfs(97)算了2次,其余的也类似,可以用hash来标记一下算过的值,如果有就直接取值

  不要再去算了,显然dp的方式更好 O(n) 对比O(2的n次方)  将对数级别优化到了O(n)

 

 

public int dfs(int n) {
      if(n<3)//如果是1或2,分别有1、2种走法直接返回即可 
      {
          return n;
      }
      else//否则递归! 
      {
         return dfs(n-1)+dfs(n-2);//利用一般表达式来求解(其实就是斐波那契数列) 
     }    
 }

 

 总结 :问多少种走法,能不能行的问题都可以尝试dp,如果要是具体的方案,如本题列出所有的走法,dp就做不了了,还是用dfs(深度优先搜索吧)

posted on 2017-08-15 17:21  李乐已存在  阅读(1665)  评论(0编辑  收藏  举报

AmazingCounters.com