例题引入
递归+记忆化
(对于重叠子问题,可以加入记忆化,把答案保存起来,加快运算速度)
动态规划
临时工
一个临时工,在一个时间段里有8份工作可以选择,每份工作工作的时间不同,每份工作的报酬也不同,但工作时间可能重贴,重叠的工作不能选择,我们要找出最大受益的选择方案(最优解)。
我们对这八个工作内容进行编号1…8。
我们将该问题拆分为一个选与不选的问题
选:
代码实现
递归实现
arr = [1,2,4,1,7,8,3]
def rec_opt(arr,i):
if i == 0:
return arr[0]
elif 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,6)
代码优化
非递归实现
import numpy as np
arr = [1,2,4,1,7,8,3]
def dp_opt(arr) :
opt = np.zeros(len(arr))
opt[0] = arr[0]
opt[1] = max(arr[0],arr[1])
for i int range(2,len(arr)) :
A = opt[i - 2] + arr[i]
B = opt[i]
opt[i] = max(A,B)
return opt[len(arr) - 1]
rec_opt(arr,6)
组合总和
代码实现
递归实现
arr = [3,34,4,12,5,2]
def rec_subsset(arr,i,s) :
if s== 0:
return True
elif i == 0:
return arr[0] == s
elif arr[i] > s :
return rec_subset(arr,i - 1,s)
else :
A = rec_subset(arr,i - 1,s - arr[i])
B = rec_subset(arr,i - 1,s)
return A or B
rec_subset(arr,len(arr) - 1,9)
代码优化
非递归实现
import numpy as np
arr = [3,34,4,12,5,2]
def dp_sunset(arr,s) :
subset = np.zeros((len(arr),s + 1),dtype = bool)
subset[:,0] = True
subset[0,:] = False
subset[0,arr[0]] = True
for i int range(1,len(arr)) :
for s in range(1,s + 1) :
if(arr[i] > s :
subset[i,s] = subset[i -1,s]
else :
A = sunset[i 1- ,s- arr[i]]
B = subset[i - 1,s]
subset[i,s] = A or B
r,c = subset.shape
return subset[r-1,c-1]
rec_subset(arr,len(arr) - 1,9)