动态规划与递归
最大值问题
给定一组序列 [1, 2, 4, 1, 7, 8, 3],求不相邻元素求和的最大值
递归
递归的思想是从后到前进行回溯
将序列记为arr,对于最后一个元素3,记为arr[6],有两种方案。
-
选择该值,则最优解为OPT[6] = OPT[4] + arr[6]
-
不选该值。则OPT[6] = OPT[5]
其中,OPT[i]为当前节点最优解的值。
根据以上规律,可得OPT(i) = max(OPT(i-2)+arr[i], OPT(i-1))
边界条件为OPT[0] = arr[0],OPT[1] = max(arr[1], arr[0])
代码
arr = [1, 2, 4, 1, 7, 8, 3]
def rec_opt(arr, i):
if i == 0:
return arr[0]
if i == 1:
return max(arr[0], arr[1])
else:
A = rec_opt(arr, i-2) + arr[i]
B = rec_opt(arr, i-1)
return max(A, B)
结果
rec_opt(arr, len(arr)-1)
15
递归的不好之处,由于它需要没有保存OPT[i]的功能,因此对于每个OPT[i]的值都要重新计算。每次增加i的值,计算量呈指数级别增长。
动态规划
动态规划的思想是从前向后依次计算当前最优解OPT[i]。
迭代公式依然是OPT(i) = max(OPT(i-2)+arr[i], OPT(i-1))。边界条件也是OPT[0] = arr[0],OPT[1] = max(arr[1], arr[0])。
代码
import numpy as np
def dp_opt(arr):
opt = np.zeros(len(arr))
opt[0] = arr[0]
opt[1] = max(arr[1], arr[0])
for i in range(2, len(arr)):
A = opt[i-2] + arr[i]
B = opt[i-1]
opt[i] = max(A, B)
return opt[-1]
结果
dp_opt(arr)
15