EVERYTHING HAPPENS FOR TH|

wnsyou

园龄:2年4个月粉丝:19关注:16

2023-10-10 00:17阅读: 53评论: 0推荐: 0

动态规划入门与线性 dp

OI-wiki Link

引入

动态规划(Dynamic Programming,DP),是一种将原问题分为一些子问题,通过局部最优解推出全局最优解。

一般来说,做一道 dp 题有 4 个步骤:

  1. 设计 dp 状态:根据几个关键信息定下状态和最优化属性。
  2. 定下拓扑序。
  3. 设计状态转移方程。
  4. 确定初始状态、目标状态和边界条件。

基本要求

dp 的基本要求有三个:

  • 最优子结构性质:即你需要保证当前状态的最优结果都是由子问题的最优结果转移而来。
  • 无后效性:即当前的选择在你的状态设计下不会影响后续的决策。
  • 子问题重叠:当有大量子问题时,需要把这些子问题的结果记录下来,防止多次求解导致效率低下。

dp 的分类

大致可分为如下几类:

  • 序列 dp
  • 背包 dp
  • 区间 dp
  • DAG 上 dp
  • 树形 dp
  • 状压 dp
  • 概率 dp
  • 还有些不会的,见 OI-wiki。

其中序列、背包、区间、概率 dp 都是线性 dp。

还有一些其他类型的 dp,比较有意思。

线性 dp

线性DP是动态规划问题中的一类问题,指状态之间有线性关系的动态规划问题。

虽然是线性 dp,但部分时间复杂度并不是纯线性的,因为线性 dp 的时间复杂度并不一定是线性的。

其他类型 dp:P1216 数字三角形

如果只是单纯的去考虑走最大数,你就会陷入坑中,考虑动态规划。

不要去看原图,只用看读入的数据,这样不抽象。

ai,j 表示第 i 行第 j 个数,那么从 (i,j) 就可以移动到 (i+1,j)(i+1,j+1)

  • 状态:dpi,j 表示从 (i,j) 往下走到第 n 行最高得分。
  • 转移:dpi,j=max(dpi+1,j,dpi+1,j+1)+ai,j
  • 拓扑序:由于 ii+1 转移而来,拓扑序就是 i 从大到小。
  • 初始状态:对于 1indpn,i=an,i
  • 目标状态:dp1,1

时间复杂度:O(n2),空间复杂度:O(n2)

序列 dp:最长上升子序列 LIS

P1020 导弹拦截 tips:这题求的两个分别是最长不上升子序列和最长上升子序列,详细证明自己搜。

B3637 最长上升子序列 tips:模板题,数据范围很小,O(n2) 可过。


给定一个长度为 n 的序列 a,求它最长上升子序列长度。

数据范围:1n5000,1ai109(1in)

a0=0

  • 状态:dpi 表示以第 i 个元素结尾的最长上升子序列长度。
  • 转移:dpi=max0j<i&&aj<ai{dpj}+1
  • 拓扑序:由于 dpi 只由 0i1 转移而来,拓扑序就是 i 从小到大。
  • 初始状态:dp0=0
  • 目标状态:max1in{dpi}

时间复杂度:O(n2),空间复杂度:O(n)


在这个数据范围中,O(n2) 可过,但如果 1n105 怎么办呢?

这也好办,只要写个离散化+树状数组/线段树优化就行了。

tips:其实这个可以贪心+二分,但不属于 dp,不谈。

时间复杂度:O(nlogn),空间复杂度:O(n)

序列 dp:最长公共子序列 LCS

P1439 【模板】最长公共子序列 tips:本题表面上求的是 LCS,实际为 LIS,但 50pts 暴力可以 O(n2) LCS 求。


给出一个长度为 n 的序列 a,还有一个长度为 m 的序列 b,求 ab 的最长公共子序列长度。

数据范围:1n,m5000,1ai,bj109(1in,1jm)

  • 状态:dpi,j 表示 a 的前 i 个元素和 b 的前 j 个元素的最长公共子序列长度。
  • 转移:dpi,j={max(dpi1,j,dpi,j1)aibjdpi1,j1+1ai=bj
  • 拓扑序:i 从小到大,i 相同则 j 从小到大。
  • 初始状态:对于 1in,dpi,0=0,对于 1im,dp0,i=0dp0,0=0
  • 目标状态:dpn,m

时间复杂度:O(n×m),空间复杂度:O(n×m)


关于 P1439:由于给定的是两个 1n 的序列,所以对于两个数 ai,aj(i<j),如果它们可以在两序列的公共子序列中,那么必然在 b 序列中的 ai 的位置小于 aj 的位置,令 cib 序列中 ai 的位置,答案就是 c​ 的最长上升子序列长度,用树状数组优化即可。

时间复杂度:O(nlogn),空间复杂度:O(n)

背包 dp:01 背包

P1048 采药 模板题。

01 背包的模型就是给出 n 个物品的占用空间 ai 和价值 bi,对于每个物品,都可以选或者不选,问在给定的背包容量 m 下最大获得的价值和。

  • 状态:dpi,j 表示考虑完前 i 个物品(草药),耗费的背包容量(时间)为 j 所获得的最大价值和。
  • 转移:dpi,j={dpi1,j1j<aimax(dpi1,j,dpi1,jai+bi)aijm
  • 拓扑序:i 从小到大。
  • 初始状态:dp0,0=0
  • 目标状态:dpn,m

时间复杂度:O(n×m),空间复杂度:O(n×m)

背包 dp:多重背包

U280382 多重背包问题 别人造的例题。

多重背包的模型就是给出 n 个物品的占用空间 ai、价值 bi 和选择的个数 ci,对于每个物品,都可以选 0ci,问在给定的背包容量 m 下最大获得的价值和。

  • 状态:dpi,j 表示考虑完前 i 个物品,耗费的背包容量为 j 所获得的最大价值和。
  • 转移:分为两种解法,见下方。
  • 拓扑序:i 从小到大。
  • 初始状态:dp0,0=0
  • 目标状态:dpn,m

solution 1

转移方法:暴力。

dpi,j=max0kci&&jk×ai{dpi1,jk×ai+k×bi}

时间复杂度:O(m×1inci),空间复杂度:O(n×m)

如果 1inci 比较大则完全接受不了,那么就需要考虑 solution 2。

solution 2

转移方法:拆分 ci 转 01 背包。

众所周知,如果你有了 1,2,4,82k,那么你可以用每个元素不超过 1 次凑出来 02k+11 中所有整数,那么考虑把 ci 尽量拆成 1,2,4,先拆一遍,最后剩下一部分单独考虑,这下就可以凑出来 0ci 中的所有整数了。

01 背包转移见上方。

时间复杂度:O(m×(n+1inlogci)),空间复杂度:O(n×m)

背包 dp:完全背包

P1616 疯狂的采药 模板题。

个人感觉比多重背包简单。

完全背包的模型就是给出 n 个物品的占用空间 ai、价值 bi,对于每个物品,都可以选无限多个,问在给定的背包容量 m 下最大获得的价值和。

  • 状态:dpi,j 表示考虑完前 i 个物品,耗费的背包容量为 j 所获得的最大价值和。
  • 转移:dpi,j={dpi1,j1jaidpi,j=max(dpi1,j,dpi,jai+bi)aijm
  • 拓扑序:i 从小到大,i 相同时 j 从小到大。
  • 初始状态:dp0,0=0
  • 目标状态:dpn,m

解释一下转移,由于每个物品可以无限选择,那么直接调用 dpi,jai 相当于再选一个,而之前并没限定选择几个,这就完美地处理了无限个物品。

时间复杂度:O(n×m),空间复杂度:O(n×m)

背包 dp:分组背包

P1757 通天之分组背包 模板题。

其实和 01 背包差不多,只要把它门分个组存储,每个组选一个处理 01 背包即可。

区间 dp

P1775 石子合并(弱化版) 敲门砖,模板题。

P1880 石子合并 标准版,模板题。


区间 dp,维护的信息为一段区间的最优化属性。

在石子合并弱化版中,为了让代价尽量小,每一段区间的代价都要尽可能小。

  • 状态:dpl,r 表示将 [l,r] 合并成一堆石子的最小代价。
  • 转移:dpl,r=minli<r{dpl,i+dpi+1,r}+lirmi
  • 拓扑序:rl 从小到大。
  • 初始状态:对于每个 1indpi,i=0
  • 目标状态:dp1,n

时间复杂度:O(n3),空间复杂度:O(n2)

石子合并的标准版中,则是将一排变成了一个环,本质没区别,只要一个环形题的常见优化套路:断环成链即可。

时间复杂度:O(8×n3),空间复杂度:O(4×n2)

dp 优化

滚动数组

通过数组的滚动来实现空间优化的目的,在 dpi, 只和 dpi1, 有关时,通常可以滚动成两个数组,方便处理。

当然还有一个叫做自我滚动的东西,只要注意好拓扑序是否满足只与 i 有关,以及自我滚动后的拓扑序即可。

记忆化搜索

并不是传统意义上的优化,但它能让你的代码逻辑更加清晰。

就是在搜索时记录当前情况下的最优解,当下一次访问时直接返回结果即可。

缺点就是递归常数大一些。

本文作者:wnsyou の blog

本文链接:https://www.cnblogs.com/wnsyou-blog/p/dp.html

版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。

posted @   wnsyou  阅读(53)  评论(0编辑  收藏  举报
  1. 1 勝利への道 安藤浩和
  2. 2 Minecraft’s End Eric Fullerton
  3. 3 月光曲完整版 贝多芬 云熙音乐
  4. 4 平凡之路 (Live版) 朴树
  5. 5 Minecraft C418
  6. 6 Paradise NiziU
  7. 7 叫我,灰原哀 龙大人不喷火
  8. 8 心机之蛙,一直摸你肚子 ——《名侦探柯南》原创同人曲 炊饭,叶辞樱,温海,寒砧,南柯柯,小茜玛姬,盛姝,阿崔Ac,贝壳初,千湛,兮茶子DaYu,乔慕,黎鹿北,起千温卿,遮阳伞,曲悠
  9. 9 战 歌 此去经年
Paradise - NiziU
00:00 / 00:00
An audio error has occurred, player will skip forward in 2 seconds.

作词 : AKIRA/Bang Chan (3RACHA)/CHANGBIN (3RACHA)/HAN (3RACHA)

作曲 : Bang Chan (3RACHA)/CHANGBIN (3RACHA)/HAN (3RACHA)/VERSACHOI

编曲 : VERSACHOI/Bang Chan(3RACHA)

昔々きいた話

ふたつの虹を超えたその向こう

光り輝く泉がある

その水面(みなも)映るのは

ほんとの自分

しあわせは今 しあわせは空

Let’s fly fly & fly We fly & fly

目と目を合わせ

信じあえるよ 感じあえるさ

Let’s fly fly & fly We fly & fly

いつか

わかるだろう

君にはもう君だけの色も形も

優しさも強さもあるんだ

上手くいかなくたって

失敗ばっかりだって

ぼくはここにいるよ

I love you so much 大好きなんだ

そのままで 大好きさ Paradise

宝物はそこにあるよ 気がついてよ

世界中探しても

君は君しかいないよ

広がる楽園 繋げよう

誰も誰もが Paradise

雨が降れば ぬかるむ道 Oh yeah

道端に咲いた花に集まる蝶を

照らす太陽は全てを温め

乾いた道に雨は降る

あたりまえだけど奇跡

小さなちっぽけな今には

大きな大きな夢が詰まっているの

悔しさに泣いたって

手を差し伸べるから

ぼくはここにいるから

I love you so much 大好きなんだ

そのままで 大好きさ Paradise

宝物は君なんだよ 気がついてよ

この惑星(ほし)の歴史にも

君は君しかいないよ

目に見えないけど確かに

ひとりひとりの Paradise

しあわせは今 しあわせは空

Let’s fly fly & fly We fly & fly

目と目を合わせ

信じあえるよ 感じあえる

だから大丈夫

心のまま行こう Paradise

加载中…

{{tag.name}}

{{tran.text}}{{tran.sub}}
无对应文字
有可能是
{{input}}
尚未录入,我来提交对应文字
评论
收藏
关注
推荐
深色
回顶
收起
点击右上角即可分享
微信分享提示