首页 > 其他分享 >动态规划dp

动态规划dp

时间:2024-04-10 23:34:01浏览次数:22  
标签:遍历 nums 问题 计算 动态 规划 dp

动态规划(Dp)

介绍

动态规划(Dynamic programming)是一种通过把原问题分解为相对简单的子问题的方式求解复杂问题的方法。 动态规划常常适用于有重叠子问题最优子结构性质的问题,动态规划方法所耗时间往往远少于朴素解法。

动态规划问题的特点

1.最优子结构性质:如果问题的最优解所包含的子问题的解也是最优的,我们就称该问题具有最优子结构性质(即满足最优化原理)。最优子结构性质为动态规划算法解决问题提供了重要线索。

2.子问题重叠性质:子问题重叠性质是指在用递归算法自顶向下对问题进行求解时,每次产生的子问题并不总是新问题,有些子问题会被重复计算多次。动态规划算法正是利用了这种子问题的重叠性质,对每一个子问题只计算一次,然后将其计算结果保存在一个表格中,当再次需要计算已经计算过的子问题时,直接从哈希表中获取结果,从而提高效率。

3.无后效性:即某阶段状态一旦确定,就不受这个状态以后决策的影响。也就是说,某状态以后的过程不会影响以前的状态,只与当前状态有关。

例如,若要解一个给定问题,我们需要解其不同部分(即子问题),再合并子问题的解以得出原问题的解。 通常许多子问题非常相似,为此动态规划法试图仅仅解决每个子问题一次,从而减少计算量: 一旦某个给定子问题的解已经算出,则将其记忆化存储,以便下次需要同一个子问题解之时直接查表。下面我们给出一道简单易懂的例题帮助掌握动态规划。

例题

找出最长的递增子序列的长度

nums=[1,5,2,4,3]

最容易想到的办法就是暴力,我们可以定义一个检索函数,传入起始数,例如从1开始,然后第二个是数可以选5、2、4、3,然后再分别看5的下一位,没有比5更大的了,结束,看2的下一位,可以取4或3,依次遍历,同时记录最长递增子序列的长度。
如图所示为遍历过程
示例

然后用循环依次将各数传入,就可以得到遍历所有起始数的结果了。
虽然这个算法可以得出正确的结果,但当下高标准的需求显然与之不符, 该算法的时间复杂度为O(2**n)*O(n),指数级别的时间复杂度,在竞赛,考试或者实际应用中都是一个不受待见的存在。

动态规划

重复示例

我们可以利用动态规划算法对齐进行优化。由上图我们可以发现,暴力算法中存在大量的重复计算,例如在外面遍历子序列1,2,,的时候就已经计算过从4开始的最大子序列的长度,但在后面遍历1,4的时候又一次进行了计算,对此,我们可以在第一次进行计算的时候将结果保存下来,之后遍历到相同的节点就不用再进行重复计算了。
这里采用记录下从i开始的最长的子序列长度从而避免重复计算(下列代码中,定义了列表L来记录)。

#定义一个函数返回其最长的递增子序列
def length_of_LIS(nums):
    n = len(nums)
    L = [1]*n      #定义一个列表存储每个数为起点的最长递增子序列数

    for i in reversed(range(n)):    #从后往前遍历,得到后边每个数为起点的递增子序列长度,当前面的数大于该数时,可直接将将其加上
        for j in range(i+1,n):         #遍历获取以该数为开始的递增子序列长度
            if nums[j]>nums[i]:
                L[i] = max(L[i],L[j]+1)

    return max(L)
nums=[1,5,2,4,3]
print(length_of_LIS(nums))

上述动态规划代码只用了两个for循环,每个循环最多执行n次因此,这段代码的时间复杂度是O(N**2),运行效率大大提高。

动态规划的一般思路

1.暴力(穷举):首先我们用最朴素的办法根据题目要求写出求解答案的思路(可以用递归等方法先写出来)。
2.记忆化搜索:如果发现过程中有大量重复计算,我们可以通过哈希表将数据记录下来,之后遍历相同节点时直接读取,避免重复计算
3.迭代形式:最后优化代码,改写成为简洁高效的迭代形式。

动态规划灵活性较强,需要勤加练习,相信每一个在黑夜中起舞的人都能迎来耀眼夺目的黎明。

**慢也好,步伐小也罢,是往前走就好。 **—佚名

标签:遍历,nums,问题,计算,动态,规划,dp
From: https://blog.csdn.net/2301_80079642/article/details/137615363

相关文章

  • Ubuntu-kali配置动态ip(简单)
    使用gedit文本编辑器打开网络接口配置文件gedit/etc/network/interfaces新增两行内容如下:autoeth0ifaceeth0inetdhcp其意思为:网卡开机自动挂载,以DHCP方式配置网卡。点击保存后叉掉。同样,使用文本编辑器打开resolv.conf配置文件。该配置文件主要作用是解析域名ged......
  • TCP与UDP
    简述TCP与UDP区别TCP(传输控制协议)和UDP(用户数据报协议)是两种常见的网络传输协议,它们在传输数据的方式、特性和用途上有着显著的区别:连接TCP:是一种面向连接的协议。在数据传输之前,必须建立一个稳定的连接。TCP连接是通过三次握手过程建立的,这个过程确保了双方的发送和接收能......
  • 动态规划Dp
    什么是动态规划?动态规划(英语:Dynamicprogramming,简称DP),是一种在数学、管理科学、计算机科学、经济学和生物信息学中使用的,通过把原问题分解为相对简单的子问题的方式求解复杂问题的方法。动态规划常常适用于有重叠子问题和最优子结构性质的问题。以上定义来自维基百科,看定义......
  • 【多UAV航迹规划】基于ACO蚁群优化的多UAV航迹规划算法matlab仿真
    目录1.算法仿真效果2.MATLAB源码3.算法概述3.1ACO蚁群优化算法原理......
  • 位数问题-dp
    #include<bits/stdc++.h>#defineintlonglong#defineendl'\n'usingnamespacestd;constintmod=12345;//dp[i][0]是前i位有偶数个3的个数//dp[i][1]是前i位有奇数个3的个数intdp[10005][2];voidsolve(){ intn; cin>>n; dp[0][0]=1; dp[0][1]=0; for......
  • ROS中自定义全局算法规划器(c++)
     ros中编写一个全局路径规划器并集成为ros插件,加载到turtlebot3机器人平台上仿真验证参考资料:ROS中自定义全局规划器(上)_算法部署_哔哩哔哩_bilibili官网教程:navigation/Tutorials/WritingAGlobalPathPlannerAsPlugininROS-ROSWiki1.建立工作空间mkdir-pjps_......
  • 掘金设置动态头像
    粘贴到控制台运行就行了avatar=后面的就是你的头像的地址,可以先去掘金评论区评论一张动图,然后拿到在线链接沾到里面就行了fetch("https://juejin.cn/web/user/update/user_info/",{"headers":{"accept":"*/*","accept-language":"zh-CN,zh;q=0.9,en;q=......
  • uniapp转译微信小程序动态样式语法问题(:style)
    这样书写之后编译成微信小程序时会出现一下情况造成此类原因是因为我们直接给了一个对象而不是字符串(即直接给字符串不会出现此类问题)而微信不能直接识别所以直接在动态赋值时加上中括号......
  • 【TensorRT】TensorRT C# API 项目更新 (1):支持动态Bath输入模型推理(下篇)
    4.接口应用关于该项目的调用方式在上一篇文章中已经进行了详细介绍,具体使用可以参考《最新发布!TensorRTC#API:基于C#与TensorRT部署深度学习模型》,下面结合Yolov8-cls模型详细介绍一下更新的接口使用方法。4.1创建并配置C#项目 首先创建一个简单的C#项目,然后添加项......
  • ADP-2-20+ 信号调节 20MHz-2GHzRF功分器 合路器
    ADP-2-20+是一款由Mini-Circuits公司出产的功分器(powerdivider)。这款功分器的工作温度规模为-40°C至85°C,贮存温度规模为-55°C至100°C。作为分路器,它的电源输入最高可达1W,内部功耗最大为0.125W。假如超越这些限制,可能会导致功分器发生永久性损坏。此外,ADP-2-20+还具有低......