Day47 | 动态规划 :线性DP 最长公共子序列最长公共子数组

ops/2024/11/28 6:14:36/

Day47 | 动态规划 :线性DP 最长公共子序列&&最长公共子数组

动态规划应该如何学习?-CSDN博客

本次题解参考自灵神的做法,大家也多多支持灵神的题解

最长公共子序列 编辑距离_哔哩哔哩_bilibili

动态规划学习:

1.思考回溯法(深度优先遍历)怎么写

注意要画树形结构图

2.转成记忆化搜索

看哪些地方是重复计算的,怎么用记忆化搜索给顶替掉这些重复计算

3.把记忆化搜索翻译成动态规划

基本就是1:1转换

文章目录

  • Day47 | 动态规划 :线性DP 最长公共子序列&&最长公共子数组
    • 1143.最长公共子序列
      • 思路分析(子问题):
      • 1.回溯 DFS
      • 2.记忆化搜索
      • 3.1:1翻译为动态规划
    • 718.最长重复子数组
    • 1035.不相交的线

1143.最长公共子序列

[1143. 最长公共子序列 - 力扣(LeetCode)](https://leetcode.cn/problems/longest-increasing-subsequence/description/)

思路分析(子问题):

设两个字符串分别是s和t

对应的最后一个字母分别是x和y

dfs(x,y)那就是s以x结尾,t以y结尾的两个字符串的最长公共子序列的长度了

那就有四种情况

1.选x这个字母也选y这个字母

2.不选x不选y

3.选x不选y

4.选y不选x

如果x==y,那肯定就是选x也选y,那肯定就是

dfs(x,y)=dfs(x-1,y-1)+1

如果说x!=y,那么就是剩下三种情况里面取一个最大值

dfs(x,y)=max(dfs(x-1,y-1),dfs(x,y-1),dfs(x-1,y))

再仔细一看,其实

dfs(x,y-1),dfs(x-1,y)包含了dfs(x-1,y-1),所以不需要这个了

dfs(x,y)=max(dfs(x,y-1),dfs(x-1,y))

不明白可以举例

dfs(x,y-1)=max(dfs(x-1,y-1),dfs(x,y-2))

递归边界:

只要x或者y小于0,那么就说明有一个字符串已经没有字母可以选择了,那么就到达了边界。

1.回溯 DFS

1.返回值和参数

i是上面x字母的下标,j是y的下标

dfs(i,j)那就是s以x结尾,t以y结尾的两个字符串的最长公共子序列的长度了

int dfs(int i,int j,string &s,string &t)

2.终止条件

只要有一个小于0就说明没有字符可以选了

if(i<0||j<0)return 0;

3.本层逻辑

相等就+1,不相等就三种选一种

		if(s[i]==t[j])return dfs(i-1,j-1,s,t)+1;elsereturn max(dfs(i-1,j,s,t),dfs(i,j-1,s,t));

完整代码:

当然,这是超时的

class Solution {
public:int dfs(int i,int j,string &s,string &t){if(i<0||j<0)return 0;if(s[i]==t[j])return dfs(i-1,j-1,s,t)+1;elsereturn max(dfs(i-1,j,s,t),dfs(i,j-1,s,t));}int longestCommonSubsequence(string text1, string text2) {return dfs(text1.size()-1,text2.size()-1,text1,text2);}
};
//lambda
class Solution {
public:int longestCommonSubsequence(string text1, string text2) {function<int(int,int)> dfs=[&](int i,int j)->int{if(i<0||j<0)return 0;if(text1[i]==text2[j])return dfs(i-1,j-1)+1;elsereturn max(dfs(i-1,j),dfs(i,j-1));};return dfs(text1.size()-1,text2.size()-1);}
};

2.记忆化搜索

就是搞一个哈希表dp,全都初始化为-1,每次返回前给哈希表dp赋值,碰到不是-1的那就是算过的,那就直接返回计算过的结果,不需要再次递归了

class Solution {
public:int dfs(int i,int j,string &s,string &t,vector<vector<int>> &dp){if(i<0||j<0)return 0;if(dp[i][j]!=-1)return dp[i][j];if(s[i]==t[j])return dp[i][j]=dfs(i-1,j-1,s,t,dp)+1;elsereturn dp[i][j]=max(dfs(i-1,j,s,t,dp),dfs(i,j-1,s,t,dp));}int longestCommonSubsequence(string text1, string text2) {vector<vector<int>> dp(text1.size(),vector<int>(text2.size(),-1));return dfs(text1.size()-1,text2.size()-1,text1,text2,dp);}
};
//lambda
class Solution {
public:int longestCommonSubsequence(string text1, string text2) {vector<vector<int>> dp(text1.size(),vector<int>(text2.size(),-1));function<int(int,int)> dfs=[&](int i,int j)->int{if(i<0||j<0)return 0;if(dp[i][j]!=-1)return dp[i][j];if(text1[i]==text2[j])return dp[i][j]=dfs(i-1,j-1)+1;elsereturn dp[i][j]=max(dfs(i-1,j),dfs(i,j-1));};return dfs(text1.size()-1,text2.size()-1);}
};

3.1:1翻译为动态规划

1.确定dp数组以及下标的含义

dp[i][j]就是dfs(I,j)

下标从1开始,下标0记录的是上面if终止条件里面的(i<0||j<0)的非法状态

2.确定递推公式

和dfs中也是对应的

				if(text1[i]==text2[j])dp[i+1][j+1]=dp[i][j]+1;elsedp[i+1][j+1]=max(dp[i][j+1],dp[i+1][j]);

3.dp数组如何初始化

都初始化为0即可

vector<vector<int>> dp(text1.size()+1,vector<int>(text2.size()+1,0));

4.确定遍历顺序

从前往后遍历即可

		for(int i=0;i<text1.size();i++)for(int j=0;j<text2.size();j++)if(text1[i]==text2[j])dp[i+1][j+1]=dp[i][j]+1;elsedp[i+1][j+1]=max(dp[i][j+1],dp[i+1][j]);return dp[text1.size()][text2.size()];

完整代码

class Solution {
public:int longestCommonSubsequence(string text1, string text2) {vector<vector<int>> dp(text1.size()+1,vector<int>(text2.size()+1,0));for(int i=0;i<text1.size();i++)for(int j=0;j<text2.size();j++)if(text1[i]==text2[j])dp[i+1][j+1]=dp[i][j]+1;elsedp[i+1][j+1]=max(dp[i][j+1],dp[i+1][j]);return dp[text1.size()][text2.size()];}
};

718.最长重复子数组

718. 最长重复子数组 - 力扣(LeetCode)

思路:

其实就是最长连续公共子序列,在上一题条件中加了一个连续

递归公式就变成了

if(nums1[i]==nums2[j])dp[i+1][j+1]=dp[i][j]+1;

因为要求的是连续,所以只要x和y不相等,那就直接是0

注意一个区别就是这里需要一个变量记录一下最大值,剩下的都一样了

动态规划

class Solution {
public:int findLength(vector<int>& nums1, vector<int>& nums2) {vector<vector<int>> dp(nums1.size()+1,vector<int>(nums2.size()+1,0));int res=0;for(int i=0;i<nums1.size();i++)for(int j=0;j<nums2.size();j++){if(nums1[i]==nums2[j])dp[i+1][j+1]=dp[i][j]+1;res=max(res,dp[i+1][j+1]);}return res;   }
};

1035.不相交的线

1035. 不相交的线 - 力扣(LeetCode)

和上面最长公共子序列一个意思,代码就只是把s换成nums1,把t换成nums2,仅此而已

动态规划

class Solution {
public:int maxUncrossedLines(vector<int>& nums1, vector<int>& nums2) {vector<vector<int>> dp(nums1.size()+1,vector<int>(nums2.size()+1,0));for(int i=0;i<nums1.size();i++)for(int j=0;j<nums2.size();j++)if(nums1[i]==nums2[j])dp[i+1][j+1]=dp[i][j]+1;elsedp[i+1][j+1]=max(dp[i][j+1],dp[i+1][j]);return dp[nums1.size()][nums2.size()];}
};

http://www.ppmy.cn/ops/137277.html

相关文章

<项目代码>YOLOv8 红绿灯识别<目标检测>

YOLOv8是一种单阶段&#xff08;one-stage&#xff09;检测算法&#xff0c;它将目标检测问题转化为一个回归问题&#xff0c;能够在一次前向传播过程中同时完成目标的分类和定位任务。相较于两阶段检测算法&#xff08;如Faster R-CNN&#xff09;&#xff0c;YOLOv8具有更高的…

第三十三章 UDP 客户端 服务器通信 - IPv4 和 IPv6

文章目录 第三十三章 UDP 客户端 服务器通信 - IPv4 和 IPv6 第三十三章 UDP 客户端 服务器通信 - IPv4 和 IPv6 UDP 支持 IPv4 和 IPv6 互联网协议。由于这些协议不兼容&#xff0c;服务器和客户端都必须使用相同的Internet协议&#xff0c;否则传输将失败。 IPv4 地址具有以…

NExT-GPT: Any-to-Any Multimodal LLM

NExT-GPT: Any-to-Any Multimodal LLM ICML 2024 Oral 整体框架 Motivation 大多数多模态模型只关注输入端的多模态理解部分模型有训练输出图片和文本交互的LLM现有的any-to-any LLM存在一定的问题&#xff1a; 不同模块之间的信息传递完全基于LLM产生的离散文本&#xff0c;级…

w058基于web的美发门店管理系统

&#x1f64a;作者简介&#xff1a;拥有多年开发工作经验&#xff0c;分享技术代码帮助学生学习&#xff0c;独立完成自己的项目或者毕业设计。 代码可以查看文章末尾⬇️联系方式获取&#xff0c;记得注明来意哦~&#x1f339;赠送计算机毕业设计600个选题excel文件&#xff0…

d3-contour 生成等高线图

D3.js 是一个强大的 JavaScript 库&#xff0c;用于创建动态、交互式数据可视化。d3-contour 是 D3.js 的一个扩展模块&#xff0c;用于生成等高线图&#xff08;contour plots&#xff09;。 属性和方法 属性 x: 一个函数&#xff0c;用于从数据点中提取 x 坐标。y: 一个函…

Excel求和如何过滤错误值

一、问题的提出 平时&#xff0c;我们在使用Excel时&#xff0c;最常用的功能就是求和了&#xff0c;一说到求和你可能想到用sum函数&#xff0c;但是如果sum的求和区域有#value #Div等错误值怎么办&#xff1f;如下图&#xff0c;记算C列中工资的总和。 直接用肯定会报错&…

Python屏幕截图

文章目录 一、安装Pillow库二、导入ImageGrab模块三、截取屏幕1. 截取全屏2. 截取特定区域 四、保存截图五、完整示例六、注意事项 Python使用ImageGrab截图主要依赖于Pillow库&#xff08;PIL库的一个分支&#xff09;&#xff0c;该库提供了ImageGrab模块来实现屏幕截图功能。…

从0开始深度学习(31)——循环神经网络

前面介绍了 n n n元语法模型&#xff0c;里面有一个叫隐状态&#xff0c;也被叫做隐藏变量&#xff0c;循环神经网络&#xff08;recurrent neural networks&#xff0c;RNNs&#xff09; 是具有隐状态的神经网络。 1 无隐状态的神经网络 以单隐藏层的多层感知机为例&#xff…