如何写动态规划算法


前言

本文的方法只能作为写动态规划过程中的一种指导,并不是所有问题都可以解决

动态规划定义

动态规划是解决搜索问题中的一种算法,该算法是利用空间换时间的思想提高算法的运行速度

如何体现出里面空间换时间的思想也有递归的思想,其实就是当我们计算dp(n)的时候是需要知道那些小规模dp(i) (i < n)的最小值,先把小规模的dp值存在dp数组中,再计算dp(n)调用dp(i)的时候就不用在重新递归那些在小规模里面递归过的数,这个把大规模的问题转成小规模的问题就是递归的感觉,所以说为什么动态规划叫做记忆化搜索,或者叫带备忘录的递归,或递归的剪枝,只是我们最后要用迭代/非递归的形式表示,递归是大规模到小规模问题拆解,动态规划是小规模到大规模迭代求解,递归是自顶而下,动态规划是自底而上,一般来说动态规划的方向和递归是相反的

剪枝的方法:解决方法就是将访问过的节点用哈希表或者dp数组进行保存,包括其节点值的信息以及所在深度的信息;在遍历的过程中,如果出现重复的节点,则直接返回。从很多题可以看出剪枝用的集合名字一般都叫做dp,从这里也可以发现记忆化搜搜和动态规划其实就是一件事,只是搜索的方向相反,也都是用dp数组存储已有的信息。
而且一般写剪枝的话要求是dfs return的不是void,而且搜索的过程是一层一层而不是往后搜索的感觉

解决方法

根据上面的分析,于是我们确定一件事,只要是能用记忆化搜索解决的问题都能用动态规划的问题解决,要解决动态规划的问题无非是解决下列几个事情:

  • 确定dp数组值的含义以及下标的含义
  • 确定状态转移方程
  • 初始化状态

根据上文的分析,在写动态规划的过程中我们可以按照以下思路来写:

  1. 用递归的方法来解决问题
  2. 将递归的方法改成记忆化搜索
  3. 通过记忆化搜索的形式来确定动态规划的方法

如何根据记忆化搜索来指导动态规划的方法呢,下面开始分析

1. 确定dp数组以及下标的含义

根据分析可知,动态规划是记忆化搜索的逆过程,所以下标一般就是在递归过程中在搜索树中一直在递归的值(也就是递归函数参数中随着递归数值在改变的值),到这里你可能理解起来非常抽象,这里举一个例子:
在这里插入图片描述
上记忆化搜索的代码:

class Solution {
   
public:
    unordered_map<int, int> dp;

    int dfs(int n)
    {
   
        if (dp.find(n) != dp.end()
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值