动态规划4种模型:暴力递归的尝试原则,如何到傻缓存dp表跟随(记忆化搜索方法),到精细化改动态规划转移方程填dp表
提示:咱只说互联网大厂的动态规划题目!不说学术研究,不说竞赛题!
暴力递归的4种经典尝试模型和尝试原则
最关键的就是这个递归函数,解题的核心在这。
动态规划的4种经典尝试模型
互联网大厂的动态规划题目中的四种经典暴力递归尝试模型:
(1)DP1:从左往右的尝试模型,关注i位置结尾,或者i位置开头的情况,或者看i联合i+1,i+2的情况,填表往往是上到下,或者下到上,左到右,右到左。
(2)DP2:从L–R范围上的尝试模型,关注L和R的情况,填表格式非常固定,主对角,副对角,倒回来填
(3)DP3:多样本位置对应的尝试模型,2个样本,一个样本做行,一个样本做列,关注i和j对应位置的情况,先填边界,再填中间
(4)DP4:业务限制类的尝试模型,比如走棋盘,固定的几个方向可以走,先填边界,再填中间。
暴力递归的尝试原则
以上4个模型的核心原则!
(1)可变参数一定不要比int类型更复杂!哪怕是boolean类型也好。
如果可变参数是数组、字符串……没法枚举,面试95%情况不会出现这种
(2)可以违反(1),但是就要保证可变参数是1维线性结构,而且只有1个可变参数,比如一个字符串String,咱们可以用dp表存str各种千奇百怪组合str的结果。
(3)如果遇到(2)这种,不必精细化优化了,直接用傻缓存跟随暴力递归函数记录结果就行(记忆化搜索方法)。
(4)可变参数越少越好,最多不要超过2个,最好1-2个,最最最好的就是1个可变参数。
如果你找到了一个方法,竟然不满足上述条件,大概率你无法写出代码来,不用尝试了。
最差也要改为傻缓存dp表跟随的动态规划
由于暴力递归代码可能会重复调用同一个递归,反复计算浪费时间
笔试面试你都需要将暴力递归改为记忆化搜索方法(也就是傻缓存dp表跟随的方法)
根据可变参数的情况,造一个dp表【可能1维表,可能2维,最差3维】,存各种变量不同状态下的最佳结果,这就是动态规划了!
这个dp表跟随暴力递归函数,如果某种状态已经求过结果,存起来,直接返回,不要再去递归了
没求过,还需要递归,不过很快就求好了。
面试尽可能改为精细化动态规划填dp表
如果笔试,记忆化搜索方法就可以过了,但是面试还不行
面试要直接明了搞出转移方程,填写dp表
这就需要直接从暴力递归代码中,改写转移方程,把dp表的临界位置(往往是0行,0列,或N-1行,或者某个特殊格子先填好),其余任意位置的ij格子,有一个依赖,依赖已经填好的格子去填写,速度非常非常快,返回我们要的结果。
面试中当遇到动态规划中有枚举行为时,尽量省掉枚举行为,把高端转移方程推导出来
在转移方程中,可能会存在枚举行为,这个枚举行为,反映到dp表上,就是ij格子左右上下,左上角,左下角啥的,可能会与ij要求的地方已经重合了,那么我们不要枚举了,只需要把枚举重合的地方,直接浓缩表现在ij格子的邻居那,拿过来用就行了。
总结
提示:重要经验:
1)暴力递归的4种经典尝试模型和尝试原则必须牢记!
2)笔试最差也要改为傻缓存dp表跟随的动态规划(也就是记忆化搜索方法),面试尽可能改为精细化动态规划填dp表,面试中当遇到动态规划中有枚举行为时,尽量省掉枚举行为,把高端转移方程推导出来
3)笔试求AC,可以不考虑空间复杂度,但是面试既要考虑时间复杂度最优,也要考虑空间复杂度最优。