最近开始学习动态规划(dp),看了《算法导论》关于动态规划的内容,慢慢也整理一些dp的经典问题上来。
适合动态规划方法求解的最优化问题应该具备的两个要素:最优子结构和子问题重叠。dp的方法相当于是把要重复求解的子问题保存下来,这样就不用重复计算了,可以节省大量的时间。
这篇博客主要讲一下斐波那契数列的递归实现和动态规划实现。这个比较简单,直接上代码:
1)斐波那契数列的递归实现
def feibo_dg(n):
if n == 1:
return 1
elif n == 2:
return 2
elif n > 2:
return feibo_dg(n-1) + feibo_dg(n-2)
1)斐波那契数列的动态规划实现
def feibo_dp(n):
f = []
f.append(1)
f.append(2)
if n > 2:
for i in range(2, n):
f.append(f[i-1] + f[i-2])
return f[n-1]
时间比较:
import time
if __name__ == '__main__':
n = 41
t1 = time.time()
dg = feibo_dg(n)
t2 = time.time()
print ('dg_time:{:.8f}'.format(t2-t1))
t3 = time.time()
dp = feibo_dp(n)
t4 = time.time()
print('dp_time:{:.8f}'.format(t4 - t3))
print ('dg result:', dg)
print('dp result:', dp)
结果如下:
dg_time:62.57764745
dp_time:0.00000000
dg result: 267914296
dp result: 267914296
其实,经典的爬楼梯问题就是斐波那契数列问题。下面提供Leetcode上的一道原题和python解决方案:
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
我的python解决方案(其实和上面的斐波那契数列的动态规划解法一样):
class Solution:
def climbStairs(self, n):
"""
:type n: int
:rtype: int
"""
if n <= 0:
return 0
f = [0 for i in range(n)]
if n >= 1:
f[0] = 1
if n >= 2:
f[1] = 2
if n > 2:
for i in range(2, n):
f[i] = f[i-1]+f[i-2]
return f[n-1]