摘自B站up主 正月点灯笼
https://space.bilibili.com/24014925/#/video
# [1,2,4,1,7,8,3]
# 选出一堆不相邻的数字,使他们的和最大
# 选出的数字不能是相邻的
import numpy as np
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)
def dp_opt(arr, i):
opt = np.zeros(len(arr))
opt[0] = arr[0]
opt[1] = max(arr[0], arr[1])
for i in range(2, len(arr)):
A = opt[i-2] + arr[i]
B = opt[i-1]
opt[i] = max(A, B)
return opt[len(arr) - 1]
arr = [3, 34, 4, 12, 5, 2]
def rec_subset(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
def dp_subset(arr, s):
subset = np.zeros((len(arr), s+1), dtype=bool)
# 所有行的第0 个 都是 True
subset[:, 0] = True
# 第 0 行 全是 False , 除了第 arr[0]
subset[0, :] = False
subset[0, arr[0]] = True
for i in range(1, len(arr)):
for s in range(1, s+1):
if arr[i] > s:
subset[i, s] = subset[i-1, s]
else:
A = subset[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]
# print(rec_subset(arr, len(arr) - 1, 9))
# print(dp_opt(arr, 6))
print(dp_subset(arr, 9))