IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 数据结构与算法 -> 动态规划DynamicPrograming解题套路总结 -> 正文阅读

[数据结构与算法]动态规划DynamicPrograming解题套路总结

????????动态规划问题应该是很多人比较头疼的,不过这类问题也是最具有技巧性的,最有意思的。

题目的一般形式

????????求最值,涉及到的方法是穷举。但穷举过程中会存在“重叠子问题”,由此造成穷举效率会很低。“最值”必存在“最优子结构”。但“穷举”并非易事,需要列出“正确的【状态转移方程】”。

????????需要使用【备忘录memoization】或【DP table】来优化穷举过程。这是一种使用空间来换取时间的策略。

题目的典型特点

????????“无后效性”,即:一旦一个子问题的求解得到结果,以后的计算过程就不会修改它。

两种解题思路

? ? ? ? ? ? ? ? ?

  • “自底而上”的递推,即从基底(base case)出发,根据状态转移方程逐步求出各个状态的解。
  • “自顶而下”的记忆化递归,即Divide and Conquer。

DP的三要素

  • 重叠的子问题:子问题出现重叠,说明应该用DP
  • 最优子结构:即判断当前节点n的“最值”的比较器。要符合“最优子结构”,子问题间必须相互独立。
  • 状态转移方程:描述问题结构的数学形式。比如,斐波拉奇数列问题中,f(n)是节点n的一个状态,它由状态f(n-1)和状态f(n-2)相加转移得到。(记住这个“状态”的例子,这对找到题目正确的状态,写出状态转移方程至关重要)

DP的难点

? ? ? ? 不知道如何确定【状态】和【选择】,也就找不到正确的【状态转移方程】。

????????【解决方案:通过技巧——数学归纳法】。

原因有二:

  • ? ? ? ? 一是因为穷举需要递归实现
  • ? ? ? ? 二是因为有的问题本身的解空间复杂,不那么容易穷举完整。比如,背包问题Longest Common Subsequence

解题策略

? ? ? ? 【状态转移方程】直接代表着暴力解法。千万不要看不起暴力解,只要写出了暴力解,优化方法无非是用备忘录或DP table,其它再无奥妙可言。

? ? ? ? 更具体一点说,找【最优子结构】的过程,其实就是证明状态转移方程正确性的过程,方程符合最优子结构就可以写出暴力解了,写出暴力解就可以看出有没有重叠子问题了。有,则优化;无,则OK。这也是套路,经常刷题的朋友应该能体会。

? ? ? ? 在实际的算法问题中,找到【状态】-->>做出【选择】-->>写出【状态转移方程】是最困难的,这也就是为什么很多朋友觉得动态规划问题困难的原因。

思维框架

????????这里总结了一个思维框架,辅助你思考 状态转移方程:

????????“明确 base case ---->>>> 明确【状态】 ---->>>> 明确【选择】 ---->>>> 定义dp 数组/函数 的含义”

? ? ? ? 按上面的套路走,最后的结果就可以套这个框架:

?如何列出正确的状态转移方程?

? ? ? ? 以?LeetCode322零钱兑换问题?? 300最长递增子序列??为例,进行讲解。

  1. 明确 base case。这个很简单,显然目标金额amount为0时,算法返回0。因为不需要任何硬币就已经凑出目标金额了。
  2. 明确“状态”,也就是原问题和子问题中会变化的变量。由于硬币数量无限,硬币的面额也是题目给定的,只有目标金额会不断地向base case靠近,所以唯一的“状态”就是目标金额amount。? ? ? 而“最长递增子序列”中,“状态”量应该是“以这个数结尾的子序列”。因为在增加元素后的序列中,会变化的变量只有元素数值。
  3. 确定“选择”,也就是导致“状态”产生变化的行为。目标金额为什么变化呢,因为你在选择硬币,你每选择一枚硬币,就相当于减少了目标金额。所以说所有的硬币的面值,就是你的“选择”。? ? ?而在“最长递增子序列”中,“选择”应该是以这个数结尾的序列中的 各个数值对应的最长递增子序列。它的“最优子结构”为前序列的所有“选择”中,以“最接近当前值(必须小于)的数”结尾的最长递增子序列的长度。
  4. 明确 dp函数/数组 的定义。我们这里讲的是“自顶向下”的解法,所以会有一个递归的dp函数。一般来说,函数的参数就是状态转移中会变化的量,也就是上面说到的“状态”;函数的返回值就是题目要求我们计算的量。就本题来说,状态只有一个,即“目标金额”,题目要求我们计算凑出目标金额所需的最少硬币数量。所以,我们可以这样定义dp函数:dp(n)表示,输入一个目标金额n,返回凑出目标金额n所需的最少的硬币数量。? ? ? ? ?而在“最长递增子序列”中,dp(n)应该是以nums[i]这个数结尾的最长递增子序列的长度。

如何找到动态规划的状态转移关系?

  1. ? ? ? ? 明确 dp数组 的定义。这一步对于动态规划问题都很重要,如果不得当或者不够清晰,会阻碍之后的步骤。
  2. ? ? ? ? 根据 dp数组 的定义,运用数学归纳法的思想,假设dp[0... i-1]都已知,想办法求出dp[i],一旦这一步完成,整个题目基本就解决了。

? ? ? ? dp数组一定是求解目标值的子问题,往往是子数组的目标值。比如题目300最长递增子序列?中“以当前值结尾的最长递增子序列的长度”,题目322零钱兑换问题?中“凑出目标金额n所需的最少的硬币数量”。

技巧

? ? ? ? 如果发现每次状态转移只需 DP table的一部分,那么可用“空间压缩”来缩小DP table 的大小,只记录必要的数据。

? ? ? ? 在阅读每个题目和解法时,多往【状态】和【选择】上靠,才能对这套框架产生自己的理解,运用自如。

一些思考

? ? ? ? 计算机解决问题其实没有任何奇技淫巧,它唯一的办法就是穷举,穷举所有可能性。算法设计无非就是“先思考如何穷举”,然后在追究“如何聪明地穷举”。? ??

? ? ? ? 动态规划的核心设计思想是“数学归纳法”。

参考链接:

????????https://labuladong.gitee.io/algo/3/

  数据结构与算法 最新文章
【力扣106】 从中序与后续遍历序列构造二叉
leetcode 322 零钱兑换
哈希的应用:海量数据处理
动态规划|最短Hamilton路径
华为机试_HJ41 称砝码【中等】【menset】【
【C与数据结构】——寒假提高每日练习Day1
基础算法——堆排序
2023王道数据结构线性表--单链表课后习题部
LeetCode 之 反转链表的一部分
【题解】lintcode必刷50题<有效的括号序列
上一篇文章      下一篇文章      查看所有文章
加:2022-05-09 12:59:06  更:2022-05-09 13:02:03 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/26 3:29:40-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码