动态规划问题及例题代码实现

动态规划Dynamic Programming

1.动态规划理论

1.1动态规划基本思想

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述
注意:斐波那契递归求解的时间复杂度为O(2n)。

在这里插入图片描述
在这里插入图片描述
子问题不独立适合动态规划算法设计。

分治:将原问题划分为互不相交的子问题,递归求解子问题,再将它们的解组合起来。

动态规划:子问题重叠的情况,不同的子问题具有公共的子子问题

在这里插入图片描述
利用动态规划需要满足:

问题中的状态满足最优性原理。 =》最优子结构
问题中的状态必须满足无后效性。 =》以前出现的状态和以前状态的变化过程不会影响将来的变化

1.2动态规划的基本步骤

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

2 举例

1.任务调度安排          在这里插入图片描述

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

2. 不相邻数字和最大

在这里插入图片描述

求一堆不相邻数字和最大,没有要求选两个,可以选多个。

在这里插入图片描述
OPT(n)指的是数据到下标为n的数字选取的最好的方案。

在这里插入图片描述
在这里插入图片描述
代码如下

#递归方程实现
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)
 
#非递归实现:dp动态规划
def dp_opt(arr):
    opt = [0 for i in range(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[-1]
 
arr1 = [4, 1, 1, 9, 1]
arr2 = [1, 2, 4, 1, 7, 8, 3]
print(rec_opt(arr1, len(arr1)-1))#13
print(dp_opt(arr1))#13
print(rec_opt(arr2, len(arr2)-1))#15
print(dp_opt(arr2))#15

3.给出一个数字和一个数组,判断是否数组中存在一些数的和为给出的数字

在这里插入图片描述

在这里插入图片描述

#递归实现
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
 
arr = [3, 34, 4, 12, 5, 2]
print(rec_subset(arr, len(arr)-1, 9))#True
print(rec_subset(arr, len(arr)-1, 10))#True
print(rec_subset(arr, len(arr)-1, 13))#False

在这里插入图片描述

在这里插入图片描述

#非递归实现:dq动态规划
def dp_subset(arr, S):
    import numpy as np
    subset = np.zeros((len(arr), S+1), dtype=bool)
    subset[:, 0] = True
    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]
arr = [3, 34, 4, 12, 5, 2]
print(dp_subset(arr, 9))#True
print(dp_subset(arr, 10))#True
print(dp_subset(arr, 13))#False
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值