zoukankan      html  css  js  c++  java
  • 剑指offer第8题--动态规划最简单讲解

    /**
     * 目标:一只青蛙一次可以跳上1级台阶,也可以跳上2级。
     * 求该青蛙跳上一个n级的台阶总共有多少种跳法(先后次序不同算不同的结果)。
     * 思路:
     * 只有1级时有1种
     * 只有两级时有2种
     * 之后每级,都有f(n-1)+f(n-2)种
     */
    public class Solution8 {
        public int JumpFloor(int target) {
            if (target ==1){
                return 1;
            }
            if (target==2){
                return 2;
            }
            int result=0,result1=1,result2=2;
            for (int i = 3; i <= target; i++) {
                result = result1+result2;
                result1 = result2;
                result2 = result;
            }
            return result;
        }
    }

    小结

    这道题其实是动态规划的思想,而且是一维的DP.

    什么是一维DP?

    即可以用一维数组表示的动态规划问题.

    动态规划的判断步骤:

    1、是否含有最优子结构

    即一个问题的最优解依赖与它所有子问题的解.

    对于这道题,由于情况可以选择跳一级,也可以选择跳两级,所以青蛙到达第n 级的台阶有两种方式

    • 一种是从第n-1 级跳上来
    • 一种是从第n-2 级跳上来

    第n级台阶的最优解依赖于跳第n-1和第n-2级的最优解的和.

    2、是否含有重叠子问题

    跳到第n-1阶的最优解依赖于第n-2和第n-3的最优解的和,并且可以类推.

    因此这是一个动态规划问题.

    动态规划的解题步骤:

    1、定义数组元素间的含义

    我们以dp[n]表示跳到第n级台阶的所有可能性,即跳上一个n级的台阶总共有 dp[n] 种跳法

    2、找出数组元素间的关系

    就是把一个规模比较大的问题分成几个规模比较小的问题,然后由小的问题推导出大的问题。也就是说,dp[n] 的规模为 n,比它规模小的是 n-1, n-2, n-3…. 也就是说,dp[n] 一定会和 dp[n-1], dp[n-2]….存在某种关系的。因此要找出他们的关系。

    那么问题来了,怎么找?

    这个怎么找,是最核心最难的一个,回到问题本身,来寻找他们的关系式,dp[n] 究竟会等于什么呢?

    对于这道题,由于情况可以选择跳一级,也可以选择跳两级,所以青蛙到达第n 级的台阶有两种方式

    • 一种是从第n-1 级跳上来
    • 一种是从第n-2 级跳上来

    由于我们是要算所有可能的跳法的,所以有dp[n] = dp[n-1] + dp[n-2]。

    3、找出初始值

    n = 1 时,dp[1] = dp[0] + dp[-1],而我们是数组是不允许下标为负数的,所以对于 dp[1],我们必须要直接给出它的数值,相当于初始值,显然,dp[1] = 1。一样,dp[0] = 0.(因为 0 个台阶,那肯定是 0 种跳法了)。于是得出初始值:

     

    dp[0] = 0.
    dp[1] = 1.

     

    但是这里有一个坑,就是当n=2时,明显有两种跳法,而不是dp[2] = dp[0]+dp[1] = 1,dp[2]可以每次跳1级,或者一次跳两级,因此dp[2] = 2.

    这里留有这样的坑是为了引起注意,找初始值一定要严谨!!!

    代码:

    public int JumpFloor(int target) {
            if (target <=1){
                return target;
            }
            if (target==2){
                return 2;
            }
    
            //定义数组的含义
            int[] dp = new int[target+1];
            //找到初始值
            dp[0] = 0;
            dp[1] = 1;
            dp[2] = 2;
    
            for (int i = 3; i < target+1; i++) {
                //找出数组元素间的关系
                dp[i] = dp[i-1]+dp[i-2];
            }
            return dp[target];
        }

     

  • 相关阅读:
    MS SQL发生死锁以及tempdb的优化资源总结
    MS SQL SERVER 簡易取得資料表實體檔案大小
    jquery选择器(转载)
    [資源]RAID是什么意思?RAID的应用
    WIN2003下安裝PHP+MYSQL資源
    MS SQL 錯誤: 15457,重要性: 0,狀態: 1
    [轉]如何修改bootini文件的/pae/awe/3gb参数
    [資源]PHP防止SQL注入
    [收藏]CSS,JS控制Table的行顏色,以及邊框
    檢查php文件中是否含有bom的php文件
  • 原文地址:https://www.cnblogs.com/Adam-Ye/p/13451529.html
Copyright © 2011-2022 走看看