一文学会动态规划

系列文章目录

注意
在学习理论之前,希望读者能看如下几个例子,有助于理解

《算法导论》学习(十七)----动态规划之钢条切割(C语言)
《算法导论》学习(十八)----动态规划之矩阵链乘(C语言)
《算法导论》学习(十九)----动态规划之最长公共子序列(C语言)



前言

本文主要讲解了动态规划的理论知识,表明动态规划的使用场景,分析了它的具体逻辑,给出了理论操作具体步骤。


一、动态规划

1.使用场景

(1)什么是动态规划

动态规划是一种用来解决一类最优化问题的编程方案,往往可以将指数时间代价的问题在多项式时间代价下解决,而这类最优化问题由如下特征:

  • 某一级的最优化问题总是可以用比低级的同类子问题来描述,称为最优子结构
  • 一般情况下,解决第n级的子问题和解决第m级的子问题的时候,都会需要解决第k级的问题(n>k,m>k),称为重叠子问题
  • 如果解决该问题采用暴力求解(就是遍历所有情况得到最优解的方案),往往时间代价是指数级的

(2)动态规划与分治策略的对比

分治策略是一种很普遍的程序设计方法,在初学的时候感觉它们有很大的相似性,难以区分,因此特别在此作出区分,希望能帮助有困惑的读者

注:想了解分治策略的读者可以参考下面的文章:
《算法导论》学习(三)---- 最大和子数组问题的分治方法
《算法导论》学习(五)---- 分治策略(递归)的时间复杂度求解

动态规划与分治的对比大致如下:

  • 都采用了用子问题来解决总问题的编程思路
  • 分治算法会采用固定的分割方式来切割问题成子问题,而动态规划的子问题切割方案由是否最优来决定,因此动态规划往往需要存储子问题的切割方式
  • 分治算法的往往采用递归的方法,设计算法是从上到下分割子问题的思路;动态规划往往采用自底向上的解决方案,即从最小的子问题开始向上解决,往往采用多层循环的方式
  • 动态规划需要存储所有的子问题的解,但是有的子问题的解对最终结果是基本没有作用的(如果忽略子问题间的比较以得到最优值这个过程);分治策略中每一个子问题的解都会对最终结果的产生有或多或少的影响。因此动态规划解决的问题的时间代价一般比较大(纯个人见解,不一定正确)
  • …(不妥之处大家请于评论区指出)

2.核心要素分析

(1)最优子结构

什么是最优子结构?

最优子结构就是指:一个问题的最优解包含它的子问题的最优解

构建结构

最优子结构的构建步骤如下:

  • 1.查看一个最优问题的解能不能用它的子问题一层一层地描述出来
  • 2.选择一种切割方案
  • 3.确定该方案需要哪些子问题来解决一个问题,包括子问题的个数和层级
  • 4.最后计算:得到最优切割方案所需要的遍历的情况数

(2)重叠子问题

什么是重叠子问题?

重叠子问题一般指:几个子问题的解决往往都需要用到相同的层级偏低的子问题。通俗的来讲,就是循环程序会重复解决一些子问题

问题解决

采用自底向上的解决结构

  • 先从最小的子问题开始解决,然后将解存入存储矩阵,之后再需要用到已解决的子问题时们直接访问存储好的最优解即可

3.操作步骤

(1)刻画问题特征

  • 首先就是要明确问题的特征是否包含两个特点:最优子结构与子问题重叠,如果满足两点,就可以考虑使用动态规划的解决方案
  • 解读问题的条件和目的,看看能不能构造出最优子结构。构造最优子结构的步骤见上
  • 如果可以构造出最优子结构,那么就要在模糊的方案上添加逻辑细节,保证所有情况下,都可以用该最优子结构方案解决好问题

(2)构建递归解

  • 根据上一步编写好的完善的最优子结构方案,来写出它的数学公式
  • 设计一些存储变量,使得递归公式得以运行。比如存储子问题最优解的存储单元
  • 明确各个逻辑条件

(3)编写算法

首先申明存储变量,主要有存储子问题解和存储分割方案的存储单元
设计循坏方案,需要自底向上的逻辑结构
返回最优值

(4)构造最优解

  • 通过切割方案的存储矩阵,获取每一次分割的方案
  • 设计递归结构,可以用递归树的方案来设计具体的细节
  • 明确具体要打印的一些数据

总结

文章的不妥之处请各位读者包涵指正。

猜你喜欢

转载自blog.csdn.net/weixin_52042488/article/details/127230982
今日推荐