暴力递归就是尝试
把问题转化为规模缩小了的同类问题的子问题
有明确的不需要继续进行递归的条件(base case)
有当得到了子问题的结果之后的决策过程
不记录每一个子问题的解
任何递归都可以写成迭代
且看暴力递归到动态规划的套路
有重复调用同一个子问题的解,这种递归可以优化
如果每一个子问题都是不同的解,无法优化也不用优化
某一个暴力递归,有解的重复调用,就可以把这个暴力递归优化成动态规划
任何动态规划问题,都一定对应着某一个有重复过程的暴力递归
但不是所有的暴力递归,都一定对应着动态规划,如 N皇后问题
设计暴力递归:重要原则 + 4种常见尝试模型!重点!
分析有没有重复解:套路解决
用记忆化搜索 -> 用严格表结构实现动态规划:套路解决
看看能否继续优化:套路解决
每一个可变参数的类型,一定不要比int类型更加复杂
原则 1 可以违反,让类型突破到一维线性结构,那必须是单一可变参数
如果发现原则 1 被违反,但不违反原则 2,只需要做到记忆化搜索即可
可变参数的个数,能少则少
一定要逼自己找到不违反原则情况下的暴力尝试!
如果你找到的暴力尝试,不符合原则,马上舍弃!找新的!
如果某个题目突破了设计原则,一定极难极难,面试中出现概率低于5%!
从左往右的尝试模型
范围上的尝试模型
多样本位置全对应的尝试模型
寻找业务限制的尝试模型
列出调用过程,可以只列出前几层,有没有重复解,一看便知
你已经有了一个不违反原则的暴力递归,而且的确存在解的重复调用
找到哪些参数的变化会影响返回值,对每一个列出变化范围
参数间的所有的组合数量,意味着表大小
记忆化搜索的方法就是傻缓存,非常容易得到
规定好严格表的大小,分析位置的依赖顺序,然后从基础填写到最终解
对于有枚举行为的决策过程,进一步优化