【算法基础】动态规划

1.动态规划思想

1]思想

分治法思想:就是将一个大问题拆分成很多小问题,小问题继续拆分成更小的问题,直到该拆分成的小问题能够很容易的被解决

2]用例子说话

一家公司,可能有总经理,部门经理,总监,组长,员工,又到了考核期,公司想选出最优秀的3个员工.一般情况下总经理会让部门经理选出自己手下最优秀的3个人,而部门经理又让总监找出自己手下最优秀3个员工,以此类推,其实这种思想就是动态规划的思想.

3]重叠子问题

不同的问题可能要求1个相同问题的解.eg:总经理想直到ABCDEFGH小组下面最优秀的人,部门经理想直到ABCD小组下面最优秀的人,总监想直到自己部门AB下最优秀的人是谁?这就有问题重叠了,他们三个都必须了解AB这两个小组中最优秀的人是谁.

4]最优子结构

最优解肯定是最优的子解转移推导而来,子解必定也是子问题的最优解推导而来.举个例子:甲总监下面最优秀的3个人肯定是从X,Y,Z提交上来的3份名单中选择最优秀的三个人。例如Q哥是X组长下面的第5名,那么他肯定不可能是甲总监下面最优秀的三个。

5]无后效性

求出来的子问题并不会因为后面求出来的改变.举个例子:X组长挑选出三个人,即便到了总经理选出所有部门最优秀的三个人,对于X组来说,最优秀的还是这3个人,不会发生改变。

2.过程

1]划分子问题

我们可以把每个子问题中的最优解认为是全局最优解

2]让计算机理解子问题

也就是状态表示,eg:f(i)(3)表示第i个人他手下最优秀的3个人

3]状态转移

大问题的最优解就等于每个子问题最优解下面的最优解

4]确定边界

确定初始状态是什么?最小子问题是什么?最终状态是什么?eg:最小子问题就是每个小组下面最优秀的人,最终状态就是整个企业,初始状态为每个小领导下面拥有的每个人的评分但不是最优的人.

经典模型

1]斐波拉契数列问题
问题描述:

前一个问题是后一个问题的基础.F(i-1)+F(i-2)=F(i)

# 1,1,2,3,5,8,13
def fblq(n):
    a=1
    b=1
    results=[]
    for i in range(n):
        results.append(a)
        a,b=b,a+b
    return results
fblq(10)
2]最长上升子序列LIS
问题描述:

输入[10,9,2,5,3,7,101,18],输出其最长上升子序列

问题分析

一定是该序列的最长的子序列;--------最长
子序列的后一个值必须比前一个大----上升
不能改变每个值在原来序列位置的顺序–上升

图解问题

在这里插入图片描述

代码解决

一般算法

def lis(nums):
    if not nums:  # 如果列表为空,就直接返回最长上升子序列为0
        return 0
    dp=[1]*len(nums)  # 初始化dp,长度和传入数据的长度相同,填充值为1,用来记录列表中每个元素初始最长上升子序列长度为1
    for i in range(len(nums)):  # 遍历列表中的每个数据
        for j in range(i):  # 遍历i个数据之前的数据
            if nums[j]<nums[i]:  # 在变量i个数据的过程中,如果这些数据当中有一个数据比我们的第i个数据小,
                dp[i]=max(dp[i],dp[j]+1)  # 那么我们就给前i个数据当中第j个数据位置对应的长度+1,查看如果当前j加完之后的子序列长度和第i位置上子序列的长度,选出最大的一个作用第i个位置上的子序列长度
    return max(dp)
a=[10,9,2,5,3,7,101,18]               
print(lis(a))

我们也可以尝试用递归去实现,这里我就不演示了.

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值