动态规划英文名为dynamic programming,其中pogramming指的是表格法,而非编写计算机程序。
基本原理
动态规划将问题分成若干个相互重叠的子问题,递归的求解子问题,保存子问题的解,再将它们的解组合起来,求出原问题的解。实际操作中,记录下子问题的结果,存储在一个表格中,使得公共的子问题只需要计算一次。
最优子结构
问题的最优解由相关子问题的最优解组合而成,一个问题的最优解包含其子问题的最优解。
总结
- 满足“最优子结构”性质的问题才能用动态规划法来解;
- 写出状态转移方程和边界条件,则问题得解;
题目
下面是一个最简单的动态规划小题目,没有之一。
有一座高度是10级台阶的楼梯,从下往上走,每跨一步只能向上1级或者2级台阶。求一共有多少种走法。
思考过程
当只剩最后一步就上到10级的时候,有几种情况呢?
两种:走了9级了 和 走了8级了
因此,状态转移方程是
F(n) = F(n-1) + F(n-2)
而边界条件呢?
F(1) = 1
F(2) = 2
开始编程
方法-1 简单递归
做了许多重复计算,时间复杂度太高,达到O(2^N)
方法-2 递归+缓存
不再做重复计算,时间复杂度只有O(N)了,而空间复杂度也是O(N)
cache = dict()
def f(n):
if n < 1:
return 0
if n in [1,2]:
return n
if cache.get(n) is not None:
return cache[n]
else:
result = f(n-1) + f(n-2)
cache[n] = result
return result
print(f(100))
方法-3 自底向上迭代法
时间复杂度还是O(N), 空间复杂度只有O(1)
int climbing_ways(int n)
{
if (n<1) return 0;
if (n==1 || n==2) return n;
int a=1, b=1, temp=0;
for(int i=3; i<=n; ++i) {
temp = a + b;
a = b;
b = temp;
}
return temp;
}
(完)