最近开始看算法导论,研究了一下动态规划,下面就开始直入主题开始记录近期看的第一个知识点动态规划。提起动态规划就不得不提几个动态规划的金典问题爬楼梯、国王金矿、背包问题。今天就仔细分析一下爬楼梯问题。

      列子 问:有一个高度为10级台阶的楼梯,从下往上走,每一次向上跨一个台阶只能是一个台阶或者两个台阶,要求用程序求出来一共有多少种算法?
      思考:如果每次都跨一个台阶 则为 1+1+1+1+1+1+1+1+1+1这种方式 、如果每次都跨两个台阶则为2+2+2+2+2+2......很多很多种,最简单暴力的算法就是写个多种循环递归调用输出所有的可行的方法,但是这种方法时效率最低的时间复杂度成指数形式递增。现在我们就开始考虑用动态规划的思路来思考这个问题,动态规划的思路就是将问题拆分、分治。

首先将问题先考虑爬楼梯的问题执行到最后一步了,只差一步就可以结束这个请款下的问题,在这个时候只有两种可能了一、从第9阶楼梯跨一步到达10阶和从第8阶一次性跨两个台阶到达10阶。假设到达第9阶台阶的方法为a种,到达第8阶的方法为b种 则到达第10阶的方法则为a+b,ok这个时候我们简写 到10阶台阶的方法为F(10),则F(10) = F(9)+F(8),然后同理继续拆分       F(9)=F(8)+F(7),F(8)=F(7)+F(6),拆分到最后当台阶只剩下1阶和二阶的时候很容易得到一个常量 F(1)=1,F(2)=2,由此可得一个公式:

F(n) = F(n-1)+F(n-2) (n>=3)

这个时候我们就得到了用到了动态规划的的概念 F(9)和F(8)是F(10)的最优子结构,F(1)=1,F(2)=2就是动态规划所谓的问题的边界,而上面所得到的公式就是状态转移方程,好了到现在为止 已近理清了我们的思路现在就要开始考虑如何解问题了,代码采用java编写

方法一、

public int getClimblingWays(int n){
if ( n<1 ) return 0;
if (n == 1)return 1;
if (n == 2)return 2;
return getClimblingWays(n-1)+getClimblingWays(n-2);
}

当然这个方法可以解决这个问题但是我们也要考虑 这个是不是运行了是很重复的计算,下面是一张所有计算节点的图

这个算法的时间复杂度是一个是一个二叉树,每一个节点都去过去进行计算即使已经计算过了 ,我们可不可以做个缓存记住已近计算好的结果呢?这里我们就引出了第二种方法

方法二、备忘录算法

public int getClimblingWaysWithCache(int n, Map<Integer,Integer> map){
if ( n<1 ) return 0;
if (n == 1)return 1;
if (n == 2)return 2;
if (map.containsKey(n)){
return map.get(n);
}else{
int val = getClimblingWaysWithCache(n-1,map)+getClimblingWaysWithCache(n-2,map);
map.put(n,val);
return val;
}
}

这种算法大大减少时间复杂度,其时间复杂发度和空间复杂度都为O(n)

到这里为止我们并未结束 我们要开始转为一下思维我们不用自顶向下的方法转化为自底向上的方法,如图所示:

在台阶大于3以后 每一个台阶的走法数之和前两个台阶数有关所有我们在可以优化一种新的方法并不不需要记住每一个子集的解,只需要记住前面两个方法的解就好,因此我们引入了第三种方法

方法三、动态规划解法

public int getClimblingWays3(int n ){
if ( n<1 ) return 0;
if (n == 1)return 1;
if (n == 2)return 2;
int a = 1;
int b = 2;
int temp =0;
for(int i = 3;i <= n ;i++){
temp = b + a;
a = b;
b = temp;
}
return temp;
}

程序从i=3开始到i=n结束 即只有F(n)n>=3的时候才开始进入循环。好了到此为止最简单的动态规划问题就全部梳理好了。

动态规划-爬楼梯问题java实现的更多相关文章

  1. climbing stairs(爬楼梯)(动态规划)

    You are climbing a stair case. It takes n steps to reach to the top. Each time you can either climb ...

  2. 【leetcode70】【动态规划】 爬楼梯

    (1 pass 一维动态规划) 爬楼梯(easy) 假设你正在爬楼梯.需要 n 阶你才能到达楼顶. 每次你可以爬 1 或 2 个台阶.你有多少种不同的方法可以爬到楼顶呢? 注意:给定 n 是一个正整数 ...

  3. Climbing Stairs爬楼梯——动态规划

    题目描写叙述: 初阶:有n层的台阶,一開始你站在第0层,每次能够爬两层或者一层. 请问爬到第n层有多少种不同的方法? 进阶:假设每次能够爬两层.和倒退一层,同一个位置不能反复走,请问爬到第n层有多少种 ...

  4. LeetCode初级算法--动态规划01:爬楼梯

    LeetCode初级算法--动态规划01:爬楼梯 搜索微信公众号:'AI-ming3526'或者'计算机视觉这件小事' 获取更多算法.机器学习干货 csdn:https://blog.csdn.net ...

  5. Leetcode题目70.爬楼梯(动态规划+递归-简单)

    题目描述: 假设你正在爬楼梯.需要 n 阶你才能到达楼顶. 每次你可以爬 1 或 2 个台阶.你有多少种不同的方法可以爬到楼顶呢? 注意:给定 n 是一个正整数. 示例 1: 输入: 2 输出: 2 ...

  6. Leetcode之动态规划(DP)专题-746. 使用最小花费爬楼梯(Min Cost Climbing Stairs)

    Leetcode之动态规划(DP)专题-746. 使用最小花费爬楼梯(Min Cost Climbing Stairs) 数组的每个索引做为一个阶梯,第 i个阶梯对应着一个非负数的体力花费值 cost ...

  7. Java实现 LeetCode 746 使用最小花费爬楼梯(递推)

    746. 使用最小花费爬楼梯 数组的每个索引做为一个阶梯,第 i个阶梯对应着一个非负数的体力花费值 costi. 每当你爬上一个阶梯你都要花费对应的体力花费值,然后你可以选择继续爬一个阶梯或者爬两个阶 ...

  8. Java实现 LeetCode70 爬楼梯

    70. 爬楼梯 假设你正在爬楼梯.需要 n 阶你才能到达楼顶. 每次你可以爬 1 或 2 个台阶.你有多少种不同的方法可以爬到楼顶呢? 注意:给定 n 是一个正整数. 示例 1: 输入: 2 输出: ...

  9. lintcode: 爬楼梯

    题目: 爬楼梯 假设你正在爬楼梯,需要n步你才能到达顶部.但每次你只能爬一步或者两步,你能有多少种不同的方法爬到楼顶部? 样例 比如n=3,中不同的方法 返回 3 解题: 动态规划题目,同时还是有顺序 ...

随机推荐

  1. DB技能数据库里把技能伤害调整

    1. MagID 技能代号 2. MagName 技能名称 3. Effect Type 效果类型(使用技能时角色的动作效果) 4. Effect 效果(技能产生的动画效果) 5. Spell 每次耗 ...

  2. Pandas数据结构(一)——Pandas Series

    Pandas 是 Python 中基于Numpy构建的数据操纵和分析软件包,包含使数据分析工作变得快速简洁的高级数据结构和操作工具.通过Pandas Series 和 Pandas DataFrame ...

  3. jquery grid 获取选中的行的数据,以及获取所有行的方法

    https://blog.csdn.net/shenqingkeji/article/details/52861319

  4. HTML入门归纳--JavaScript

    本人一直在从事.net的开发,界面都是采用的WPF,近期花了一个多月进行HTML前端的学习,在这里呢进行学习总结和归纳. 本系列将主要分为4个模块: 控件 样式 布局 JavaScript 根据多年W ...

  5. bugku 宽带信息泄露

    首先下载文件 下载完成后发现是一个后缀名为 bin 的文件 然后找百度查一下这是什么文件的后缀名 看一下题目 然后用软件routerpassview打开(搜的教程) 然后打开文件 搜索username ...

  6. 数学算法(一):快速求斐波那契数第n项通过黄金分割率公式

    有一个固定的数学公式= =,不知道的话显然没法应用 首先黄金分割率接近于这个公式, (以下为黄金分割率与斐波那契的关系,可跳过) 通过斐波那契数列公式 两边同时除以 得: (1) 注意后一项比前一项接 ...

  7. DVWA全级别之SQL Injection(SQL注入)

    DVWA全级别之SQL Injection(注入)   DVWA简介 DVWA(Damn Vulnerable Web Application)是一个用来进行安全脆弱性鉴定的PHP/MySQL Web ...

  8. 激活windows系统

    1.下载KMS 2.如图所示,双击KMSpico看是否正常运行 3.双击KMSpico正常后出现以下界面 4.点击红色按钮 5.等自动退出就是激活成功,大概半年需要激活一次

  9. android nfc功能开发

    链接:Android NFC开发详细总结   https://blog.csdn.net/zhwadezh/article/details/79111348 链接2:Android NFC功能 简单实 ...

  10. java NIO - DirectBuffer 和 HeapBuffer

    问题 : DirectBuffer 属于堆外存,那应该还是属于用户内存,而不是内核内存? FileChannel 的read(ByteBuffer dst)函数,write(ByteBuffer sr ...