动态规划专题——passage_1

动态规划组成部分:

1:确定状态

      — 确定最后一步(最优策略)

      — 抽象子问题 

2:归纳转移方程

— 不知道且需要的信息,加进状态里

3:初始条件和边界情况

4:计算顺序

— 一般为从左到右,从上到下

 

例一  最值型动态规划(col1.2)

题目描述:

有2 、 5 、 7三种硬币,求最少几枚能拼够一个整数?(3.-2)

状态转移:

f[x] = min { f[x-2] + 1, f[x-5] + 1, f[x-7]+1 }  (3.-3)

初始条件: (3.4)

f ... -1 0 1 2 3 4 5 6 ... 27
  nan nan 0 nan 1 nan 2 1 3 ... 5

小笔记:

感觉入门的动态规划问题还是像由递归延伸出来的记忆化搜索。(2.2)

 

例二 计数型动态规划

题目描述:

[ m , n ]网格,人从(0,0)出发,每步可以向下或向右走一步,有多少种方法走到左下角?

状态转移:

f[i][j] = f[i-1][j] + f[i][j-1]

边界状况:

i = 0 or j = 0  ——f[i][j] = 1

初始条件:

f[0][0] = 1

 

例三 存在型动态规划

题目描述:

n块石头在x轴 0 ... n-1位置,青蛙想从0跳到n-1,在第i块石头上能跳ai,问能否跳到n-1上?

状态转移:

f[i] = OR(任意)0<=i<j(f[i] AND i + a[i] >= j ) 

 

例四 序列型动态规划

题目描述:

一排N栋房子,每栋要漆成红、蓝、绿三色之一,相邻不能漆成同色,第i栋房子漆成红、蓝、绿的开销分别是[i][0] 、[i][1] 、[i][2],问漆这些房子的最小花费?

确定状态:

最后一栋房子[n-1]必为三色之一,但确定这一状态还需要知道[n-2]的颜色、知道[n-2]为各种颜色时的最小花费。

边界条件:

f[0][OR] = 0

状态转移:

f[i][0] =min { f[i-1][i] + cost[i-1][0] , f[i-1][2] + cost[i-1][0] }      类比,三个颜色三个方程

 

例五 划分型动态规划

题目描述:

有段A~Z组成的字母串信息被加密成数字串,A-1,B-2,....Z-26,给定加密后字串S[0...N-1],问有多少种解密方式?

确定状态:

求前[n-1]和[n-2]个字符解谜方式数之和。

状态转移:

f[i] = f[i-1] ( S[i-1]能对应一个字母 ) + f[i-2] ( S[i-2]S[i-1]能对应一个字母 )

边界条件:

f[0] = 1

 

坐标型动态规划

给定一个序列或网格,需要找到序列中某个/某些子序列或网格中的某条路径

— 某种性质最大/最小

— 基数

— 存在性

动态规划方程f[i]中的下标i表示以ai为结尾的满足条件的子序列的性质,f[i][j]中的下标i,j表示以格子(i,j)为结尾的满足条件的路径的性质

— 最大值/最小值

— 个数

— 是否存在

 

例六 一维坐标型动态规划

题目描述:最长单调连续子序列

给定a[0],...,a[n-1],找到最长的连续子序列i,i+1,i+2,...,j,使得a[i] < a[i+1] < ... < a[j],或者a[i] > a[i+1] > ... >a[j],输出长度 j - i + 1.

例:输入  [ 5 , 1 , 2 , 3 , 4 ]

输出 4

确定状态:

找最长连续上升子序列,再将序列颠倒所求就是最长连续下降子序列。

设f[j] = 以a[j]结尾的最长连续上升子序列的长

情况一:a[j]  ans = 1

情况二:a[j-1] < a[j]  ans = ans( a[j-1] ) + 1

状态转移:

f[j] = max{1 , f[j-1] + 1 ( j > 0  AND a[j-1] < a[j] ) } 

计算顺序:

f[j] =以a[j]结尾的最长连续上升子序列的长度

max{ f[0] , ... , f[n-1] }

 

例七 二维坐标型动态规划

题目描述:

给定[m , n]网格,每个格子(i , j)里都有一个非负数A[i][j],求一个从左上角(0 , 0)到右下角的路径,每一步只能向下或者向右走一步,使得路径上的格子里的数字之和最小,输出最小的数字和。

确定状态:

无论何种方式到达右下,最后一步只有两种可能。

状态转移:

f[i][j] = min{ f[i-1][j] , f[i][j-1] } +A[i][j]

初始边界:

f[0][0] = A[0][0]            i = 0 OR j = 0,前一步方向唯一

空间优化:滚动数组

我们发现计算时我们只用了两行数组,开数组时只用开 f[0][0...n-1] 和 f[1][0...n-1] 交替赋值使用即可。

 

例八 上难度了

题目描述:

给定[m , n]网格,每个格子可能为空,也可能有个敌人,也可能有一堵墙。只能在某个空格子里放一个炸弹,炸弹会炸死同行同列的所有敌人,但是不能穿透墙。求最多能炸死几个敌人?

输入:

0 E 0 0
E 0 W E
0 E 0 0

输出: 3

题目分析:

每个格子上下左右求一下,时间复杂度指数级。TEL不用想。动态规划的思想,这题确实也不是很好想。

确定状态:

将爆炸拆解成四个方向,假设所有格子都能放炸弹,单独计算。

有敌人的格子,格子里敌人被炸死,并继续向上爆炸。

有墙的格子,炸弹不能炸死任何敌人。

则,在(i , j)格放一个炸弹,它向上能炸死的敌人数是:

— (i , j)格为空地:( i-1 , j )格向上能炸死的敌人数

— (i , j)格为敌人:( i-1 , j )格向上能炸死的敌人数 + 1

— (i , j)格为墙:0

最后求四个方向,max{ Up[i][j] + Down[i][j] + Left[i][j] +Right[i][j] }

初始条件:

Up[0][j] = 0,如果(0 , j)格不是敌人

Up[0][j] = 1,如果(0 , j)格是敌人

转移方程:

Up[i][j] = { Up[i-1][j] (如果i , j是空地) OR Up[i-1][j] + 1 (如果i , j是敌人) OR 0  (如果i , j是墙) }

空间优化:

可以开一个两行的Up滚动数组,计算四个方向,等规模ans数组存最后结果。

 

例九 序列 + 位操作型动态规划

位操作(二进制)

&与, |或,  ^异或,  !非

逐位操作

题目描述:

给定N,要求输出0 , 1 , ... , N 的每个数的二进制表示里的1的个数

输入:5

输出:[ 0,1, 1, 2, 1, 2 ]

状态转移:

f[i] = f[i>>1] + ( i mod 2 )

动态规划去除重复计算

 

例十 序列型动态规划

题目描述:

一排N栋房子,每栋要漆成K种颜色之一,相邻不能漆成同色,第i栋房子漆第j种颜色的花费是cost[i][j],问漆这些房子的最小花费?

确定状态:

设油漆前i栋房子并且房子i-1是颜色1,颜色2,...颜色K的最小花费分别为f[i][1],f[i][2],...,f[i][K]

状态转移:

f[i][1] = min{ f[i-1][2] + cost[i-1][1],f[i-1][3] + cost[i-1][1],...,f[i-1][K] + cost[i-1][1] }

K个式子我们不能全写出来,写一个for循环,优化下:

f[i][j] = mink!=j { f[i-1][k] } + cost[i-1][j]

每次求一组元素中除了一个元素之外其他元素的最小值,求最小的两个值即可。

假如最小值是f[i-1][a],次小值是f[i-1][b]

对于j = 1,2,3,...,a-1,a+1,...,K   

f[i][j] = f[i-1][a] + cost[i-1][j]

f[i][a] = f[i-1][b] + cost[i-1][a]

 

例十一 序列型动态规划

题目描述:

有一排N栋房子(0~N-1),房子i里有A[i]个金币,有个贼人想选择一些房子偷金币,他不能偷任何相邻两家的,请问这个贼人最多能偷多少金币?

确定状态:

第N-1栋房子,要么偷,要么不偷。不偷时问题变成了求前N-2栋房子最多能偷多少。

设f[i][0]表示不偷房子 i-1 的前提下,前 i 栋房子中最多能偷多少金币

设f[i][1]表示偷房子 i-1 的前提下,前 i 栋房子中最多能偷多少枚金币

转移方程:

f[i][0] = max { f[i-1][0],f[i-1][1] }

f[i][1] = f[i-1][0] + A[i-1]

发现不偷时 f[i][0] = f[i-1][1] 故存在重复,可以简化成以为:

f[i] = max{ f[i-1] ,f[i-2] + A[i-1] }

初始边界:

f[0] = 0,f[1] = A[0], f[2] = max{ A[0],A[1] }

 

例十二 例十升级

题目描述:

有一圈N栋房子(0~N-1),房子i里有A[i]个金币,有个贼人想选择一些房子偷金币,他不能偷任何相邻两家的,请问这个贼人最多能偷多少金币?

确定状态:

情况1:没偷房子0,就变成了1~N-1序列问题

情况2:没偷房子N-1,就变成了0~N-2序列问题

环形问题,针对性分析有什么情况,化作序列问题。

posted @ 2021-08-20 22:34  anyiya  阅读(105)  评论(0编辑  收藏  举报