动态规划系列

1.最长递增子序列:

(1)动态规划解法:分配一个dp数组用来用来存放以当前下标的元素为结尾的最长子序列,那么最终结果就是dp数组中的最大值。dp数组初始值设为1,如何来设计动态规划:判断此下标元素与之前所有下标元素的大小关系,可能就会产生一系列的新子序列,但是只选择最长的那一个。最后找出dp数组中的最大值。

(2)二分搜索解法:利用纸牌的思想:只能把点数小的牌压到和它大与等于的牌上,如果当前牌数不满足条件就新开一个牌堆,把这张牌放进去;如果当前牌有多个队可供选择,则选择最左边的那一堆放置。最后牌的堆数就是最长子序列的长度。因此每次对一个新牌进行放置时都要找到满足要求的最左侧的牌堆,就要进行二分搜索(因为最终结果是牌的堆数,所以用一维数组就可以,可以直接替换不需要保存),如果找不到就新开辟一个牌堆,此牌放入堆顶(所谓堆顶也就是无所谓),记录牌堆树的元素加一。

2.二维递增子序列(信封嵌套):

思路分析:先对宽度 w 进行升序排序,如果遇到 w 相同的情况,则按照高度 h 进行降序排序。之后把所有的 h 作为一个数组,在这个数组上计算出的 LIS(最长递增子序列 Longest Increasing Subsequence) 的长度就是答案。也可以反过来对长度先进行升序,然后对宽度进行降序。

3.最大子数组问题:

子数组是连续性的,根LIS最大的不同,因此dp数组的含义定义有区别,dp[ i ]的两种选择:要么与前面的相邻子数组连接,形成一个更大的子数组,要么不与其相连,自成一派,自己作为一个子数组。实际完全不需要一个dp数组,因为dp里的元素时实时更新的,最大的一定是最后一个元素,所以完全可以用两个变量(dp-i, dp-i-1)来替代,减少空间复杂度。

4.最优子结构与dp数组的遍历方向:

最优子结构是很多问题具有的性质。

dp数组的遍历方向拿二维数组来说基本有三中:正向、反向、斜向。

动态规划问题最重要的推导状态转移方程,猜测最终结果可能是从哪个方向来的。

有时候需要考虑最终结果的位置来确定是哪种遍历方式,有时候多种遍历方式都可以。

5.编辑距离:

题目:对于两个字符串:s1,s2,可以对s1进行三种操作:插入、删除、替换一个字符。计算将s1转换成s2最少需要多少次操作。

思路:解决两个字符串的动态规划问题一般都是用两个指针 i ,j 分别指向两个字符串的最后,然后一步一步往前走,缩小问题个规模。

两种容易处理的情况:就是 j 走完时如果 i 没走完,那么只能用删除操作将s1 缩短为 s2,反之,若 i 走完是 j 还没走完那么只能用插入操作将s2剩余的字符全部插入到s1中。用迭代实现。

利用dp二维数组来存储已经计算好的字符串来减少巨量计算量,动态规划中的dp数组的初始化比较不同设两字符串的长度分别为length1,length2,那么数组的大小应为length1+1 * length2 +1,第0行和第0列的分别表示i,j 到头是应该进行的操作数量,分别等于剩余的列数和行数,dp[i+1][j+1]要考虑四种情况:1.待比较的两字符相等;2.需要插入;3,需要替换;4,需要删除。因此要比较后三种哪种操作带来的操作数最小。以此类推,最小操作数将存放在dp[length1][length2]中,将其返回即可。

相关推荐
马剑威(威哥爱编程)1 小时前
除了递归算法,要如何优化实现文件搜索功能
java·开发语言·算法·递归算法·威哥爱编程·memoization
算法萌新——12 小时前
洛谷P2240——贪心算法
算法·贪心算法
湖北二师的咸鱼2 小时前
专题:二叉树递归遍历
算法·深度优先
重生之我要进大厂2 小时前
LeetCode 876
java·开发语言·数据结构·算法·leetcode
KBDYD10103 小时前
C语言--结构体变量和数组的定义、初始化、赋值
c语言·开发语言·数据结构·算法
Crossoads3 小时前
【数据结构】排序算法---桶排序
c语言·开发语言·数据结构·算法·排序算法
自身就是太阳3 小时前
2024蓝桥杯省B好题分析
算法·职场和发展·蓝桥杯
孙小二写代码4 小时前
[leetcode刷题]面试经典150题之1合并两个有序数组(简单)
算法·leetcode·面试
little redcap4 小时前
第十九次CCF计算机软件能力认证-1246(过64%的代码-个人题解)
算法
David猪大卫4 小时前
数据结构修炼——顺序表和链表的区别与联系
c语言·数据结构·学习·算法·leetcode·链表·蓝桥杯