问题一:爬楼梯
有一座高度是10级台阶的楼梯,从下往上走,每跨一步只能向上1级或者2级台阶。要求用程序来求出一共有多少种走法。
动态规划的思想:dynamic programming,一种分阶段求解决策问题的数学思想。即大事化小,小事化了。
分两部分:问题建模和求解问题。
(1)问题建模
上述问题假设只差一步走到第10级,则F(10)=F(9)+F(8)。(最优子结构)
.......
我们归纳出的公式如下:
F(1)=1;
F(2)=1;(边界)
.........
F(n)=F(n-1)+F(n-2);(状态转移公式)
动态规划中包含三个重要的概念:最优子结构、边界和状态转移公式。
(2)求解问题
方法1:递归算法
package com.dynamicProgramming_lc;
public class DpDemo {
public static void main(String[] args) {
// TODO Auto-generated method stub
System.out.println(getClimbingWays(10));
}
private static int getClimbingWays(int n){
if (n<0) {
return 0;
}
if (n==1) {
return 1;
}
if (n==2) {
return 2;
}
return getClimbingWays(n-1)+getClimbingWays(n-2);
}
}
分析可知:算法时间复杂度过高,达到了O(2^n),观察递归可知,出现了很多重复的f(*),可将f(*)放入map中,用时取出即可。
方法2:备忘录算法
package com.dynamicProgramming_lc;
import java.util.HashMap;
import java.util.Map;
public class DpDemo {
public static void main(String[] args) {
// TODO Auto-generated method stub
Map<Integer, Integer> map = new HashMap<Integer, Integer>();
System.out.println(getClimbingWays(map, 10));
}
private static int getClimbingWays(Map<Integer, Integer> map, int n){
if (n<0) {
return 0;
}
if (n==1) {
return 1;
}
if (n==2) {
return 2;
}
if (map.containsKey(n)) {
return map.get(n);
} else {
int value = getClimbingWays(map, n-1)+getClimbingWays(map, n-2);
map.put(n, value);
return value;
}
}
}
方法3:动态规划算法
上述均为自顶向下计算,换种思路,自底向上计算,不使用递归。只需记住上次和上上次的走法数即可。
package com.dynamicProgramming_lc;
public class DpDemo {
public static void main(String[] args) {
// TODO Auto-generated method stub
System.out.println(getClimbingWays(10));
}
private static int getClimbingWays(int n){
if (n<0) {
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 = a + b;
a = b;
b = temp;
}
return temp;
}
}
其时间复杂度为O(n),空间复杂度为O(1)。
上述问题只有一个变化维度,较简单。
问题二:国王和金矿
123
123
本文探讨了经典的爬楼梯问题,通过动态规划的方法解决了该问题,并对比了几种不同的算法实现方式,包括递归算法、备忘录算法及动态规划算法。
1807

被折叠的 条评论
为什么被折叠?



