动态规划Dp算法

重叠子问题

引入:
斐波那契数列
在这里插入图片描述在这里插入图片描述
递归时间复杂度太高,考虑把已经算出的结果保存起来,减少重复工作

选与不选:
本题要求在下图中找到能够连接的任务,要使之不重叠并能使各任务红字相加达到最大。
对每个任务i,当这个任务被选择时,前面必然有部分不重叠,部分重叠,将不重叠部分相加,比如OPT(8) = 4+OPT(5)
当这个任务不被选择时,
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
例:
选出一串数字中一些数字,使得数字不相邻,且数字和最大
1241783

import numpy as np
arr = [1,2,4,1,7,8,3]
def rec_opt(a, i): #递归
    if i == 0:
       return a[i] 
    elif i == 1:
        return max(a[0], a[1])
    else :
        A = rec_opt(a, i-1)
        B = rec_opt(a, i-2)+a[i]
        return max(A, B)
rec_opt(arr, 6)

def dp_opt(a, i):
    opt = np.zeros(len(a))
    opt[0] = a[0]
    opt[1] = max(a[0], a[1])
    for i in range(2, len(a)):
        opt[i] = max(opt[i-1], opt[i-2]+a[i])
    return opt[len(a)-1]
dp_opt(arr, 6)

在一串数字中选择几个数字使得相加之和等于给定数字,存在则返回true,不存在则返回false
例:
3,34,4,12,5,2
s = 9
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

arr = [3, 34, 4, 12, 5]
def rec_subset(a, i, s):
    if s == 0:
        return True
    elif i == 0:
        return a[i] == 0
    elif a[i] > s:
        return rec_subset(a, i-1, s)
    else:
        return rec_subset(a, i-1, s-a[i]) or rec_subset(a, i-1, s)
rec_subset(arr, 4, 12)     


import numpy as np
def dp_subset(a, s):
    subset = np.zeros((len(a), s+1), dtype = bool)
    subset[:, 0] = True
    subset[0, :] = False
    subset[0, a[0]] = False
    for i in range(1, len(a)):
        for j in range(1, s+1):
            if a[i] > j:
                subset[i][j] = subset[i-1][j]
            else:
                A = subset[i-1][j]
                B = subset[i-1][j-a[i]]
                subset[i, j] = A or B
    r, c = subset.shape
    return subset[r-1, c-1]
print dp_subset(arr, 9)
print dp_subset(arr, 13)

subset[ i, s]代表当a[i]之前是否能凑出s

https://www.bilibili.com/video/BV12W411v7rd/?spm_id_from=333.788.videocard.0

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值