代码随想录-动态规划总结

动规五部曲

  • 确定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 + 1i的元素。
对于二维子序列来说,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

函数开始处理的特殊情况由初始化决定

posted @   chanxe  阅读(24)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 微软正式发布.NET 10 Preview 1:开启下一代开发框架新篇章
· 没有源码,如何修改代码逻辑?
· NetPad:一个.NET开源、跨平台的C#编辑器
· PowerShell开发游戏 · 打蜜蜂
· 凌晨三点救火实录:Java内存泄漏的七个神坑,你至少踩过三个!
点击右上角即可分享
微信分享提示