动态规划 学习笔记(1)

一、动态规划简介

动态规划 dynamic programming )相比程序算法,更多的是一种 思 想 ① 思想^{①} !!!

1. 动态规划步骤

1.刻画 一个最优解 结构特征
2. 递归地定义最优解的值
3. 计算最优解的值,通常采用 自底向上的方法
4.利用 计算出来的信息 构造 一个最优解

这是《算法导论》上动规步骤的阐述 (不讲人话) ,相信初学会一脸懵逼,什么是 一个最优解,什么是 结构特征 ,怎么 计算,怎么采用 自底向上 的方法,计算出了什么 信息,怎么去 构造一个最优解。( 我也不会 ) ② ^{②}

2. 动态规划解释 ③ ^{③}

最优化结构的特征

2.1 最优子结构 :问题的最优解包含子问题的最优解,因此,反过来,就是由子问题的最优解也可以推出问题的“最优解”(但因为可能存在多个最优解,因此(步骤中)说 一个最优解,也就有了求字典序最小的方案的问题( 重构),后续会提到)

2.2 无后效性 :说简单点就是,未来不影响现在,现在(而不是过去)决定未来 (是不是和我们生活一样)

a.在推导后面阶段状态的时候,我们只关心前面阶段的状态值,而不关心这个状态是怎么一步步推导出来的
b.某阶段状态一旦确定,就不受之后阶段的决策影响

2.3 重叠子问题 :问题的递归算法会反复地求解相同的子问题,相对地,动态规划算法则会将子问题的解存在一张表内,方便下次决策(动态规划英文名中 programming 深刻地表现了这一特征)

动态规划就是利用 所解的问题的最优化结构的性质特征,通过现在的状态值与未来状态值的转移( 状态转移方程 ),来设计算法的一种思想

状态:事物表现出来的形态,或所处的状况

3. 另一种解题步骤

闫氏DP法 ⟶ \longrightarrow 集合 角度考虑问题
(可以略微了解一点离散数学)

动态规划
状态表示
状态计算
集合
属性:MAX/MIN/COUNT
划分

做题中会利用到,到时更深入理解


① DP思想,会在做题的情况下逐渐清晰、理解
②个人理解,理解是逐渐深化(做题)的过程
③如果有问题,会来更新,也希望得到指正

二、数字三角形模型

2.1 数字三角形问题

有一个由非负整数组成的三角形,第一行只有一个数,除了最下行之外每个数的左下方和右下方各有一个数(图略,来源–紫书P259),从每一行的数开始,每次可以往左下或右下走一格,直到走到最小行,把沿途的数全部加起来,问这个数最大是多少?

步骤描述 :

状态值: 从底部走到该点的最大值,记 f i , j f_{i, j} fi,j

最优子结构: 最优解即顶部的 f i , j f_{i, j} fi,j,可想它是由左下或右下的最优解而来,可用反证法证明(假设不是最优解)

无后效性: f i , j f_{i, j} fi,j 的大小,由 f i + 1 , j f_{i +1,j} fi+1,j f i + 1 , j + 1 f_{i+1, j+1} fi+1,j+1,即左下和右下两个决定,不受过去(更下面的行)状态值影响

重叠子问题: 若采用递归,则会反复地计算某个点的最优解(由最优子结构得出)

由上面描述,现在与未来的状态值转换的方程 (状态转移方程) 也就出来了, f i , j f_{i, j} fi,j = max( f i + 1 , j f_{i +1,j} fi+1,j, f i + 1 , j + 1 f_{i+1, j+1} fi+1,j+1) + w ,这里采用自底向下,事实上也可以采用自顶向下(记忆化递归)

这道题虽然很简单,但可以 延申 出一类题目

2.2 延申(模型)

以数字三角形走格规律,建边,那就变成了一张 有向无环图DAG

因此,数字三角形问题也就 衍生变成了简单DAG上的问题,也就可以用数字三角形问题的思想解决DAG上的问题,可以用来求 最长路MAX、最短路MIN、路径计数COUNT

2.3模型特征 ① ^{①}

状态值:一般为所问求的答案

最优子结构:来源自走格规律的 前向点的最优解,沿着边,转移至当前点点,得到当前的最优解

无后效性:注意状态值转移过程中,不会受过去(未来)影响,只通过现在状态值影响未来状态值(有时可约束取消掉过去的影响,比如过去选择的最后1个字母 好像与这模型无关 ),如若不满足,尝试新的状态值定义

重叠子结构:反复求解,可存表中(如记忆化递归)

状态转移方程:由上诉性质,和走图规律,建立


① 个人理解,如有错,或更好的解释,求评论告知,会改

2.4 案例及练习

过河卒 洛谷P1002

思路:看作图,走图规律:向下、向右、多了个限制,很容易出来状态转移方程

方格取数 洛谷P7074

走方格 洛谷P6855

巴比伦塔 The Tower of Babylon UVA437(洛谷)

思路:抽象成图

三、最长上升子序列模型

3.1最长上升子序列问题(LIS)

给定n个整数 A 1 A_{1} A1, A 2 A_{2} A2,…… A n A_{n} An,按从左到右的顺序选出尽量多的整数,组成一个上升子序列。

解法:
可以用上面数字三角形模型,把该问题抽像类似为图上的问题,走图规律是小于当前点的前向点可以走(转移)过来,因此 状态转移方程 很简单就出来了 f i f_{i} fi = max{0, f j f_{j} fj| j < i and A j A_{j} Aj < A i A_{i} Ai } + 1

这是一类特殊问题,因此可以抽像出模型。

此外,还可以用到一种贪心的方法把时间复杂度优化到O(nlogn),这里略。

3.2 最长公共子序列问题(LCS)

给两个子序列A和B,求长度最长的公共子序列,如 序列1:1, 5, 2, 6, 8, 7 , 序列2: 2, 3, 5, 6, 9, 8, 4 的最长公共子序列为5, 6, 8.

步骤描述:

状态值: 前i项和前j项的LCS长度,记 f i , j f_{i, j} fi,j

最优子结构: 最优解肯定是由最优解转换而来。假设不是,如某解 + 最后1步,LCS长度,这是替换某解为前最优解,这是发现LCS长度 ≥ \geq 原来的LCS长度(等于是因为可能都是最优解),因此证明了最优子结构

无后效性: f i , j f_{i, j} fi,j 的大小,由最后1步之前的LCS转移过来,并不关心前面序列是怎么样的

重叠子问题: 若采用递归,则会反复地计算某个点的最优解(由最优子结构得出)

状态转移方程: A j A_{j} Aj = A i A_{i} Ai f i , j f_{i,j} fi,j = f i − 1 , j − 1 f_{i - 1,j - 1} fi1,j1 + 1, 当 A j ≠ A i A_{j} \neq A_{i} Aj=Ai f i , j f_{i,j} fi,j = max{ f i − 1 , j f_{i - 1,j } fi1,j f i , j − 1 f_{i,j - 1} fi,j1 }

由上面例子,发现很多时候,状态值计算(转移)的依据一般为最后1步不同的时候

为什么讲LCS,因为有时LCS 可以转换为 LIS 问题(离散化),后面有题目体现!

3.3 案例及练习

合唱队形 洛谷P1091

思路: 正反2次LIS,然后加起来最大即可

导弹问题 洛谷P1020

思路: LIS问题,其中涉及到O(nlogn)方法(有多种,只是贪心思想,用其他维护)学习

友好城市 洛谷P2782

思路:LCS 转化成 LIS 问题

Greatest Common Increasing Subsequence HDU1423

思路:最长公共上升子序列(LCIS)

结束语

蒟蒻匍匐前进,欢迎各位大佬神犇指正,咕咕咕

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值