动态规划的案例python(1)

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)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值