首页 > 其他分享 >动态规划方法论

动态规划方法论

时间:2024-08-20 16:51:10浏览次数:11  
标签:方法论 规划 数组 公式 动态 递推 dp

动态规划

动态规划,英文:Dynamic Programming,简称DP,如果某一问题有很多重叠子问题,使用动态规划是最有效的。

所以动态规划中每一个状态一定是由上一个状态推导出来的,这一点就区分于贪心,贪心没有状态推导,而是从局部直接选最优的,

我在这里举一个典型的动态规划的问题——背包问题:

例如:有N件物品和一个最多能背重量为W 的背包。第i件物品的重量是weight[i],得到的价值是value[i] 。每件物品只能用一次,求解将哪些物品装入背包里物品价值总和最大。

动态规划中dp[j]是由dp[j-weight[i]]推导出来的,然后取max(dp[j], dp[j - weight[i]] + value[i])。

但如果是贪心呢,每次拿物品选一个最大的或者最小的就完事了,和上一个状态没有关系。

所以贪心解决不了动态规划的问题。

而且很多讲解动态规划的文章都会讲最优子结构啊和重叠子问题啊这些,这些东西都是教科书的上定义,晦涩难懂而且不实用。

大家知道动规是由前一个状态推导出来的,而贪心是局部直接选最优的,对于刷题来说就够用了。

上述提到的背包问题,后序会详细讲解。

动态规划的解题步骤

做动规题目的时候,很多同学会陷入一个误区,就是以为把状态转移公式背下来,照葫芦画瓢改改,就开始写代码,甚至把题目AC之后,都不太清楚dp[i]表示的是什么。

这就是一种朦胧的状态,然后就把题给过了,遇到稍稍难一点的,可能直接就不会了,然后看题解,然后继续照葫芦画瓢陷入这种恶性循环中

状态转移公式(递推公式)是很重要,但动规不仅仅只有递推公式。

动态规划五部曲

对于动态规划问题,我将拆解为如下五步曲,这五步都搞清楚了,才能说把动态规划真的掌握了!

  1. 确定状态变量dp以及dp的含义
  2. 确定递推公式
  3. dp数组如何初始化
  4. 确定遍历顺序
  5. 举例推导dp数组

一些同学可能想为什么要先确定递推公式,然后在考虑初始化呢?

因为一些情况是递推公式决定了dp数组要如何初始化!

确定状态变量dp

  • 在动态规划中,某一步的状态dp,是一定由前面的状态,或者后面的状态所推出来的,所以说我们一定要理解dp数组到底代表着什么,它的含义十分重要,如果没有搞懂一道题的dp数组的含义是什么,那么我们就不能说掌握了这道题!
  • 所以说状态变量dp是非常重要的!

递推公式

后面的讲解中我都是围绕着这五点来进行讲解。

可能刷过动态规划题目的同学可能都知道递推公式的重要性,感觉确定了递推公式这道题目就解出来了。

其实 确定递推公式 仅仅是解题里的一步而已!

一些同学知道递推公式,但搞不清楚dp数组应该如何初始化,或者正确的遍历顺序,以至于记下来公式,但写的程序怎么改都通过不了。

后序的讲解的大家就会慢慢感受到这五步的重要性了。

动态规划应该如何debug

相信动规的题目,很大部分同学都是这样做的。

看一下题解,感觉看懂了,然后照葫芦画瓢,如果能正好画对了,万事大吉,一旦要是没通过,就怎么改都通过不了,对 dp数组的初始化,递推公式,遍历顺序,处于一种黑盒的理解状态。

写动规题目,代码出问题很正常!

找问题的最好方式就是把dp数组打印出来,看看究竟是不是按照自己思路推导的!

一些同学对于dp的学习是黑盒的状态,就是不清楚dp数组的含义,不懂为什么这么初始化,递推公式背下来了,遍历顺序靠习惯就是这么写的,然后一鼓作气写出代码,如果代码能通过万事大吉,通过不了的话就凭感觉改一改。

这是一个很不好的习惯!

做动规的题目,写代码之前一定要把状态转移在dp数组的上具体情况模拟一遍,心中有数,确定最后推出的是想要的结果

然后再写代码,如果代码没通过就打印dp数组,看看是不是和自己预先推导的哪里不一样。

如果打印出来和自己预先模拟推导是一样的,那么就是自己的递归公式、初始化或者遍历顺序有问题了。

如果和自己预先模拟推导的不一样,那么就是代码实现细节有问题。

这样才是一个完整的思考过程,而不是一旦代码出问题,就毫无头绪的东改改西改改,最后过不了,或者说是稀里糊涂的过了

这也是我为什么在动规五步曲里强调推导dp数组的重要性。

举个例子哈:一些同学可能代码通过不了,会把代码抛到讨论群里问:我这里代码都已经和题解一模一样了,为什么通过不了呢?

发出这样的问题之前,其实可以自己先思考这三个问题:

  • 这道题目我举例推导状态转移公式了么?
  • 我打印dp数组的日志了么?
  • 打印出来了dp数组和我想的一样么?

如果这灵魂三问自己都做到了,基本上这道题目也就解决了,或者更清晰的知道自己究竟是哪一点不明白,是状态转移不明白,还是实现代码不知道该怎么写,还是不理解遍历dp数组的顺序。

总结

  • 这一篇是动态规划的整体概述,讲解了什么是动态规划,动态规划的解题步骤,以及如何debug。

  • 动态规划是一个很大的领域,今天这一篇讲解的内容是整个动态规划系列中都会使用到的一些理论基础。

  • 在后序讲解中针对某一具体问题,还会讲解其对应的理论基础,例如背包问题中的01背包,leetcode上的题目都是01背包的应用,而没有纯01背包的问题,那么就需要在把对应的理论知识讲解一下。

  • 我在后面也会更新很多关于动态规划的经典题型以及解题方法。

注明:

标签:方法论,规划,数组,公式,动态,递推,dp
From: https://www.cnblogs.com/Tomorrowland/p/18369754

相关文章

  • 《深度解读代理模式:静态代理与动态代理的详尽剖析》
    代理模式一、引言在Java开发中,代理模式是一种非常重要的设计模式,它为其他对象提供一种代理,以控制对这个对象的访问,在访问对象和目标对象之间起到中介作用。Java中的代理按照代理类生成时机不同分为静态代理和动态代理,而动态代理又有JDK代理和CGLib代理两种。本文将......
  • 设计模式之cglib动态代理
    什么是动态代理呢?动态代理就是在java进程运行时,通过字节码技术,动态的生成某个类的代理类。在这个代理类中,我们可以做一些额外的操作,一方面仍然保持原有的方法的能力,另外一方面还增强了这些能力。听着是不是AOP有点像,没错,动态代理就是AOP的技术基石。在这之前我曾经写过两篇相关的......
  • Day35 动态规划Part3
    目录任务01背包(KAMA46)DP思路滚动数组思路416.分割等和子集思路任务有n件物品和一个最多能背重量为w的背包。第i件物品的重量是weight[i],得到的价值是value[i]。每件物品只能用一次,求解将哪些物品装入背包里物品价值总和最大。01背包(KAMA46)DP思路dp[i][j]为[0,i]的所有物......
  • pod数据持久化-pv与pvc资源及动态存储StorageClass
    一、pc与pvc的概念在传统的存储卷挂载,比如说nfs,它虽然能够实现我们大多数的生产场景,但是,耦合性比较高;举例:假设,我们要将集群从“阿里云”迁移到我们私有云服务器上,并改变存储卷挂在的类型,就无法实现,必须使用原有的存储卷类型;比如我们阿里云的存储卷是nfs,我们线下服务器的存储卷......
  • 权值线段树与动态开点线段树
    权值线段树(维护一段值域)用线段树维护桶实质上是维护一段值域中数字出现次数例:\(1,5,4,6,7,3,8,4,5,6\);根:\(1-8\);左儿子:\(1-4\);右儿子:\(5-8\);询问目前出现第\(k\)小数字从根节点出发,如果根节点权值\(>k\)则证明存在第\(k\)小;以此类推问:如果值域很大,线段树炸了怎......
  • 动态dp
    T1一共\(n\)颗糖果,第\(i\)颗的价值为\(a[i]\),你不能连着选两颗,请问你的选到的最大价值为多少显然有如下写法:设\(dp[i][0/1]\)表示选到了第\(i\)颗,第\(i\)颗选或不选显然有转移:\(dp[i][0]=max(dp[i-1][0],dp[i-1][1])\)\(dp[i][1]=max(dp[i-1][......
  • 动态规划:找出每个位置为止最长的有效障碍赛跑路线
    目录问题定义思路解题过程复杂度code问题定义        你打算构建一些障碍赛跑路线。给你一个 下标从0开始 的整数数组 obstacles ,数组长度为 n ,其中 obstacles[i] 表示第 i 个障碍的高度。对于每个介于 0 和 n-1 之间(包含 0 和 n-1)的下......
  • 动态dp & 矩阵加速递推
    广义矩阵乘法我们定义两个矩阵\(A,B\)在广义矩阵乘法下的乘积为\(C\),其中\[C=\begin{bmatrix}\max\limits_{i=1}\limits^{m}A_{1,i}+B_{i,1}&\max\limits_{i=1}\limits^{m}A_{1,i}+B_{i,2}&\dots&\max\limits_{i=1}\limits^{m}A_{1,i}+B_{i,k}\\\......
  • 计算机视觉实战项目3(图像分类+目标检测+目标跟踪+姿态识别+车道线识别+车牌识别+无人
     车辆跟踪及测距 该项目一个基于深度学习和目标跟踪算法的项目,主要用于实现视频中的目标检测和跟踪。该项目使用了YOLOv5目标检测算法和DeepSORT目标跟踪算法,以及一些辅助工具和库,可以帮助用户快速地在本地或者云端上实现视频目标检测和跟踪!教程博客_传送门链接-------......
  • C/C++语言基础--指针三大专题详解2(指针与数组关系,动态内存分配,代码均可)
    本专栏目的更新C/C++的基础语法,包括C++的一些新特性前言指针是C/C++的灵魂,和内存地址相关联,运行的时候速度快,但是同时也有很多细节和规范要注意的,毕竟内存泄漏是很恐怖的指针打算分三篇文章进行讲解,本专题是二,介绍了指针和数组的关系、动态内存如何分配和释放等问题专题......