• climbing stairs(爬楼梯)(动态规划)


    You are climbing a stair case. It takes n steps to reach to the top.

    Each time you can either climb 1 or 2 steps. In how many distinct ways can you climb to the top?

    Note: Given n will be a positive integer.

    Example 1:

    Input: 2

    Output: 2

    Explanation: There are two ways to climb to the top. 1. 1 step + 1 step 2. 2 steps

    Example 2:

    Input: 3

    Output: 3

    Explanation: There are three ways to climb to the top. 1. 1 step + 1 step + 1 step 2. 1 step + 2 steps 3. 2 steps + 1 step

    爬楼梯,一次可以爬一级或者两级楼梯。问爬到n级楼梯有多少中方法。

    分析:爬到n,可以是从n-1级楼梯一次爬上来,也可以是从n-2级一次走两步上来(不能从n-2走一步再走一步,因为走一步就会去到n-1级,重复)。所以有公式f(n)=f(n-1)+f(n-2)。

    递归是可以解决的,但是递归会出现超时的情况。

    所以使用动态规划。动态规划也没有什么特别之处,就是把一个大问题分解成许多个子问题,子问题解决了,大问题也就解决了。比如这里的f(n),可以先求f(3),再根据状态方程求后一项,。。。,。这就是动态规划。

    递归都可以转成动态规划。

    动规解题的一般思路

        1. 将原问题分解为子问题

    •     把原问题分解为若干个子问题,子问题和原问题形式相同或类似,只不过规模变小了。子问题都解决,原问题即解决。
    •     子问题的解一旦求出就会被保存,所以每个子问题只需求 解一次。

        2.确定状态

    •     在用动态规划解题时,我们往往将和子问题相关的各个变量的一组取值,称之为一个“状 态”。一个“状态”对应于一个或多个子问题, 所谓某个“状态”下的“值”,就是这个“状 态”所对应的子问题的解。
    •     所有“状态”的集合,构成问题的“状态空间”。“状态空间”的大小,与用动态规划解决问题的时间复杂度直接相关。

        3.确定一些初始状态(边界状态)的值

        以“爬楼梯”为例,初始状态就是f(1),f(2),值就是数字值。

        4. 确定状态转移方程

         定义出什么是“状态”,以及在该“状态”下的“值”后,就要找出不同的状态之间如何迁移――即如何从一个或多个“值”已知的 “状态”,求出另一个“状态”的“值”(递推型)。状态的迁移可以用递推公式表示,此递推公式也可被称作“状态转移方程”

        从递推公式出发,就可以先求出小问题的解,最后大问题的解就出来了。如先求出f(3),f(4)...

    代码:

    class Solution {
        public int climbStairs(int n) {
           if(n<=0) return 0;
            if(n==1) return 1;
            if(n==2) return 2;
            /*
                根据规则可以知道f(n)=f(n-1)+f(n-2);但是不能用递归,因为数字很大时,递归会超时。
                这里其实是动态规划,思路还是根据上面的公式。一直从前往后加。自己在草稿纸上多写几项就知道规律了。
                这里:one_step_before,表示f(n-1),two_step_before表示f(n-2).total表示f(n)。
                比如,f(1)=1,f(2)=2,则f(3)=3,此时要算下一个f(4),f(4)=f(3)+f(2),所以对于f(4)而言,two_step_before=one_step_before(f2),one_step_before=total(f3);
            */
            int one_step_before=2;
            int two_step_before=1;
            int total=0;
            for(int i=3;i<=n;i++){
                total=one_step_before+two_step_before;
                two_step_before=one_step_before;
                one_step_before=total;
            }
            return total;
        }
    }
  • 相关阅读:
    信息爆炸时代,对待信息的三种方式
    Spring事务管理
    归并排序和快速排序的衍生问题
    Linux之Shell命令
    程序员找工作的干货经验
    css3 Transition动画执行时有可能会出现闪烁的bug
    布尔值
    null, undefined理解
    js文字的无缝滚动(上下)
    vue实现文字上下滚动
  • 原文地址:https://www.cnblogs.com/xiaolovewei/p/8072489.html
Copyright © 2020-2023  润新知