1:题目
:一组数中不能相邻的几个数选出来组成的和最大
比如[4,1,1,9,1] 我们可以选择[4,1,1],[1,9],[4,9],但是只有[4,9]比较大
例如:
标号i:0 1 2 3 4 5 6
—arr: 1 2 4 1 7 8 3
分析
设opt(i) 为最佳选法。我们倒着看,
开始是opt(6),如果选6号位的3,
- 我们就只能选opt(4)+3,
- 如果不选3,就选opt(5)
opt(4) 又是 选7的话就只能选opt(2)+7,不选7 就是opt(3)
opt(5) 也是选与不选,选就是opt(3)+8,不选就是opt(4)
可以看到opt(4) ,opt(3)都存在重叠。
**opt(i) = max(- 选 opt(i-2)+arr[i]
- 不选 opt(i-1)
)**
递归出口就是:
opt(0) = arr[0]
opt(1) = max(arr[0],arr[1])
代码实现:
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)
result = rec_opt(arr, 6)
print(result) # 输出15
上面是递归解法,会有很多重复,算法复杂度时O(2**n)
下面我们把它存在数组中做:
def dp_opt(arr):
opt = 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]
result = dp_opt(arr)
print(result)