1.动态规划算法
来源:互联网 发布:deepin15 linux 教程 编辑:程序博客网 时间:2024/05/16 11:09
一、问题
有一座高度是10级的楼梯,从下往上走,每跨一步只能向上1级或者2级台阶。求出走到10级一共有多少种走法。
二、分析
走到10级的情况有两种:
从第8级走两步到第10级从第9级走一步到第10级
那么到8级和9级有几种情况呢?
8级: 从第6级走两步到第8级 从第7级走一步到第8级9级: 从第7级走两步到第9级 从第8级走一步到第9级
如果我们假设从0到8有m种走法,从0到9有n种走法,那么0到10级就有m+n种走法。
我们假设求x级台阶走法为函数F(x),那么
F(10) = F(9) + F(8)
那么F(9)、F(8)怎么计算呢?同理不难得出F(x) = F(x-1) + F(x-2),x>=3
F(9) = F(8) + F(7)F(8) = F(7) + F(6)
如果不断枚举下去,总体会是这样的
F(10) = F(9) + F(8)F(9) = F(8) + F(7)F(8) = F(7) + F(6)...F(3) = F(2) + F(1)F(2) = 2F(1) = 1
答案就显而易见了,只要我们从下向上计算就可算出结果了。
F(3) = F(2) + F(1) = 3F(4) = F(3) + F(2) = 5F(5) = F(4) + F(3) = 8..........
接下来什么是动态规划算法呢?
动态规划算法是通过拆分问题,定义问题状态和状态之间的关系,使得问题能够以递推的方式去解决
其中有三个核心的概念:
* 最优子结构
* 边界
* 状态转移公式
最优子结构
F(10) = F(9) + F(8),F(9)、F(8)就是F(10)的最优子结构
边界
F(1)、F(2)可以直接算出,无需继续计算,这就是这个问题的边界,没有边界是无法得出结果的。
状态转移公式
F(x) = F(x-1) + F(x-2); x>=3,这个就是转换不同阶段的状态转移公式,将F(10)的计算转换为了F(9) + F(8)
三、编程实现
1.递归
public static int getCountByRecursion(int x) { if (x < 1) { return 0; } if (x == 1) { return 1; } if (x == 2) { return 2; } return getCountByRecursion(x -1) + getCountByRecursion(x - 2); }
2.优化递归
private static HashMap<Integer, Integer> map = new HashMap<Integer, Integer>(); public static int getCountByRecursionMore(int x) { if (x < 1) { return 0; } if (x == 1) { return 1; } if (x == 2) { return 2; } //如果map包含该值,直接返回 if (map.containsKey(x)) { return map.get(x); } //不包含就继续计算 int value = getCountByRecursionMore(x -1) + getCountByRecursionMore(x - 2); map.put(x, value); return value; }
3.迭代求解
public static int getCountByIteration(int x) { if (x < 1) { return 0; } if (x == 1) { return 1; } if (x == 2) { return 2; } int a = 1; int b = 2; int temp = 0; for (int i = 3; i < x; i++) { temp = a + b; a = b; b = temp; } return temp; }
主方法
public static void main(String[] args) { //使用递归 long start1 = System.nanoTime(); log.info("递归算法:" + getCountByRecursion(25) + ";耗时:" + (System.nanoTime() - start1)); //递归优化 long start2 = System.nanoTime(); log.info("递归优化:" + getCountByRecursionMore(25) + ";耗时:" + (System.nanoTime() - start2)); //迭代 long start3 = System.nanoTime(); log.info("迭代:" + getCountByIteration(25) + ";耗时:" + (System.nanoTime() - start3)); }
看下运行的结果,效率的差别非常之大
[01:50:35.465] [INFO] com.kingboy.dynamicprogramming.DynamicMain.main(DynamicMain.java:18) 递归算法:121393;耗时:1826965[01:50:35.468] [INFO] com.kingboy.dynamicprogramming.DynamicMain.main(DynamicMain.java:21) 递归优化:121393;耗时:93255[01:50:35.468] [INFO] com.kingboy.dynamicprogramming.DynamicMain.main(DynamicMain.java:24) 迭代:75025;耗时:8726
完整示例参考github项目algorithm模块下的dynamicprogramming
阅读全文
0 0
- 1.动态规划算法
- 算法--动态规划算法
- 算法1.动态规划 游艇租赁问题
- 动态规划算法剖析
- 动态规划算法
- 初识动态规划算法
- 动态规划算法
- 动态规划算法剖析
- 动态规划算法
- 动态规划算法剖析
- 动态规划算法
- 动态规划算法实现
- 动态规划算法
- 动态规划算法
- 动态规划算法之一
- 动态规划算法备忘
- 动态规划 --压缩算法
- 动态规划算法
- hello csdn
- 把知乎丁香医生的文章及回答转pdf
- Android 开发之 Gradle那些事儿(三)
- 滚动条实现RGB颜色的调制(窗体程序)--JAVA基础
- C++ String简易实现
- 1.动态规划算法
- mybatis 异常处理:Invalid bound statement (not found)
- 1054. 求平均值 (20)
- Scala处理XML文件(一)
- Scala处理XML文件(二)
- 什么是TTL、RS232、RS485?
- C#--数组
- vue.js 组件 之 prop 传递数据
- python多线程