代码随想录-动态规划总结
动规五部曲
- 确定dp数组(dp table)以及下标的含义
- 确定递推公式
- dp数组如何初始化
- 确定遍历顺序
- 举例推导dp数组
dp数组必须是由已经计算好的状态推导而来
当前状态只依赖个别状态的可以用滚动数组
01背包
二维数组dp[i][j],第一个坐标i代表从0~i物品中选择,j代表背包体积;要将第0行和第0列进行初始化;遍历顺序无所谓;
滚动数组dp[j], j代表背包体积;将数组初始化为0即可;先遍历物品再遍历背包(倒叙:为了不重复多拿同一物品)(因为倒叙,防止最终结果只拿一个物品)
子集问题有时也可以转化为背包问题
成对销毁的问题也可以转换为背包,比如加减来求和用01背包模板:确定背包容量,确定物品体积和价值,确定元素不可重复取
背包要求装满,则将背包除了首个元素外全部初始化为负无穷
完全背包
相对于01背包来说,一维数组的情况下,遍历背包时不需要倒叙
排列组合问题
回溯可以得到具体方案
动态规划用于求方案数组合数:先遍历物品再遍历背包,这样物品就不会出现顺序不同但元素相同的组合了
排列数:先遍历背包再遍历物品,这样就会统计到不同顺序的元素了
树形dp
后序遍历
用一个一维数组来记录状态
递归过程记录了每一个节点的状态
股票问题
对每一天设置可能的不同状态,买入,卖出,条件状态
如果规定买卖次数,则每天的状态与买卖次数有关。
子序列问题
最长递增子序列和最长连续递增子序列:dp[i]都表示以i结尾的状态,区别就是不连续的子序列要比较
i
元素与0 ~ i - 1
之间的元素, 连续的区间只要比较i + 1
与i
的元素。
对于二维子序列来说,dp[i][j],i和j表示实际数组中i - 1和j - 1位置的情况,这样方便初始化其中一维不选元素的情况,比如nums1中不取元素,nums2中取第一个元素,则dp[0][1];
编辑距离问题
二维数组,一维代表一个字符串
分支条件为两个字符串某个字符的比较
dp[i - 1][j]指的是删除第一维度的字符串,或者表示添加第二个维度字符串,替换操作:dp[i - 1][j - 1]
回文问题
dp[i][j]两个维度,i和j表示子串的开头和结尾
单个元素也要考虑
顺序从下到上,从左到右
连续的回文用bool数组存结果,不连续的用int
attention
函数开始处理的特殊情况由初始化决定
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 微软正式发布.NET 10 Preview 1:开启下一代开发框架新篇章
· 没有源码,如何修改代码逻辑?
· NetPad:一个.NET开源、跨平台的C#编辑器
· PowerShell开发游戏 · 打蜜蜂
· 凌晨三点救火实录:Java内存泄漏的七个神坑,你至少踩过三个!