动态规划<九>两个数组的dp

news2025/1/30 8:32:39

目录

引例

 LeetCode经典OJ题

1.第一题

2.第二题

 3.第三题

 4.第四题

 5.第五题

 6.第六题

 7.第七题

引例

OJ传送门LeetCode<1143>最长公共子序列

画图分析:

使用动态规划解决

1.状态表示 ------经验+题目要求

经验为选取第一个字符串的[0,i]区间以及第二个字符串的[0,j]区间作为研究对象,再根据实际的题目要求,确定状态表示

dp[i][j]表示:字符串s1的[0,i]区间以及字符串s2的[0,j]区间内的所有子序列中,最长公共子序列的长度

2.状态转移方程----根据最后一个位置的状况,分情况讨论

3.初始化

在关于字符串的dp问题中,空串也是有研究意义的

在这里引入空串是为了方便我们后面的初始化,根据状态转移方程会发生越界的为第一行和第一列,因此可以采用多加一行和一列的方式来完成初始化

 

注意下标的映射关系

4.填表顺序   从上往下,从左往右

5.返回值 dp[m][n](m,n分别为字符串的长度)

具体代码:

int longestCommonSubsequence(string s1, string s2) 
    {
        int m=s1.size(),n=s2.size();
        vector<vector<int>> dp(m+1,vector<int>(n+1));
        for(int i=1;i<=m;++i)
            for(int j=1;j<=n;++j)
                if(s1[i-1]==s2[j-1]) dp[i][j]=dp[i-1][j-1]+1;
                else dp[i][j]=max(dp[i-1][j],dp[i][j-1]);
        return dp[m][n];
    }

 LeetCode经典OJ题

1.第一题

OJ传送门LeetCode<1035>不相交的线

画图分析:

 动态规划各步与引例相同

具体代码:

int maxUncrossedLines(vector<int>& nums1, vector<int>& nums2) 
    {
        int m=nums1.size(),n=nums2.size();
        vector<vector<int>> dp(m+1,vector<int>(n+1));
        for(int i=1;i<=m;++i)
            for(int j=1;j<=n;++j)
                if(nums1[i-1]==nums2[j-1]) dp[i][j]=dp[i-1][j-1]+1;
                else dp[i][j]=max(dp[i-1][j],dp[i][j-1]);
        return dp[m][n];
    }

2.第二题

OJ传送门LeetCode<115>不同的子序列

画图分析:

 使用动态规划解决

1.状态表示

dp[i][j]表示:字符串s的[0,j]区间内所有的子序列中,有多少个字符串t的[0,i]区间内的子串

2.状态转移方程

根据字符串s的子序列的最后一个位置包不包含s[j]

3.初始化

会发生越界的为第一行和第一列,可以采用多加一行和一列的方式来初始化

根据状态表示,i=0的这一行是去s中寻找空串,有一个,j=0的这一列是空串中寻找t的子串,是找不到的,初始化为0

4.填表顺序

从上往下,从左往右

5.返回值  dp[m][n]

具体代码:

int numDistinct(string s, string t) 
    {
        const int MOD=1e9+7;
        int m=t.size(),n=s.size();
        vector<vector<int>> dp(m+1,vector<int>(n+1));
        for(int i=0;i<=n;++i) dp[0][i]=1;//初始化
        for(int i=1;i<=m;++i)
            for(int j=1;j<=n;++j)
            {
                dp[i][j]+=dp[i][j-1];
                if(t[i-1]==s[j-1])
                {
                    dp[i][j]+=dp[i-1][j-1];
                    dp[i][j]%=MOD;
                }
            }
        return dp[m][n];
    }

 3.第三题

OJ传送门LeetCode<44>通配符匹配

画图分析:

使用动态规划解决

1.状态表示

dp[i][j]表示:p[0,j]区间内的子串能否匹配s[0,i]区间内的子串

2.状态转移方程 --根据最后一个位置的状况来划分问题

3.初始化  初始化第一行和第一列

第一行i=0时,s是空串,当j不断增大时,当第一次遇到不是*的就会匹配不成功,为false

第一列j=0时,p是空串,去匹配p的话,就会匹配不成功,为false

4.填表顺序   从上往下,从左往右

5.返回值   dp[m][n] 

具体代码:

bool isMatch(string s, string p) 
    {
        int m=s.size(),n=p.size();
        s=" "+s,p=" "+p;
        vector<vector<bool>> dp(m+1,vector<bool>(n+1));
        dp[0][0]=true;
        for(int i=1;i<=n;++i) 
        {
            if(p[i]=='*') dp[0][i]=true;
            else break;
        }
        for(int i=1;i<=m;++i)
        {
            for(int j=1;j<=n;++j)
            {
                if(p[j]=='*')
                    dp[i][j]=dp[i][j-1] || dp[i-1][j];
                else
                    dp[i][j]=(p[j]=='?' || s[i]==p[j])&& dp[i-1][j-1];
            }
        }
        return dp[m][n];
    }

 4.第四题

OJ传送门LeetCode<10>正则表达式匹配

画图分析:

使用动态规划解决

1.状态表示

dp[i][j]表示p[0,j]区间内的子串是否能匹配s[0,i]区间内的子串

2.状态转移方程------根据最后一个位置的状态,分情况讨论

3.初始化

初始化第一行和第一列

当i=0,s为空串,p必须保持偶数位为*,当第一次没有遇到*时,就初始化为false

当j=0,p为空串,去匹配s的话,都是不成功的,初始化为false

4.填表顺序

从上往下,从左往右

5.返回值    dp[m][n]

具体代码:

bool isMatch(string s, string p) 
    {
        int m=s.size(),n=p.size();
        s=" "+s,p=" "+p;
        vector<vector<bool>> dp(m+1,vector<bool>(n+1));
        dp[0][0]=true;

        for(int j=2;j<=n;j+=2)
            if(p[j]=='*') dp[0][j]=true;
            else break;
        
        for(int i=1;i<=m;++i)
        {
            for(int j=1;j<=n;++j)
            {
                if(p[j]=='*')
                    dp[i][j]=dp[i][j-2] || (p[j-1]=='.' || p[j-1]==s[i]) && dp[i-1][j];
                else
                    dp[i][j]=(p[j]==s[i] || p[j]=='.') && dp[i-1][j-1];
            }
        }
        return dp[m][n];
    }

 5.第五题

OJ传送门LeetCode<97>交错字符串

画图分析:

 使用动态规划解决

可以做个预处理,每个字符串添加一个空白字符

1.状态表示

dp[i][j]表示s1[1,i]区间内的字符串以及s2[1,j]区间内的字符串,能否拼接成s3[1,i+j]区间内的字符串

2.状态转移方程

3.初始化    初始化第一行和第一列

i=0即s1为空串,字符串s2与s3逐个往后匹配,当第一次遇到不匹配时,初始化为false

j=0即s2为空串,与上面一样

4.填表顺序    从上往下,从左往右

5.返回值    dp[m][n]

具体代码:

 bool isInterleave(string s1, string s2, string s3) 
    {
        int m=s1.size(),n=s2.size();
        if(m+n!=s3.size()) return false;
        s1=" "+s1,s2=" "+s2,s3=" "+s3;

        vector<vector<bool>> dp(m+1,vector<bool>(n+1));
        dp[0][0]=true;
        for(int i=1;i<=n;++i)//初始化第一行
            if(s2[i]==s3[i]) dp[0][i]=true;
            else break;
        for(int i=1;i<=m;++i)//初始化第一列
            if(s1[i]==s3[i]) dp[i][0]=true;
            else break;
        
        for(int i=1;i<=m;++i)
            for(int j=1;j<=n;++j)
                dp[i][j]=(s1[i]==s3[i+j] && dp[i-1][j])
                || (s2[j]==s3[i+j] && dp[i][j-1]);
                
        return dp[m][n];
    }

 6.第六题

OJ传送门LeetCode<712>两个字符串的最小ASCII码删除和

画图分析:

 会发现当两个字符串删除完之后剩下的为公共子序列,而公共子序列有很多,根据题意,我们只需求出两个字符串里面所有的公共子序列中,ASCII码的最大和,即可满足最小删除和

使用动态规划解决

1.状态表示

dp[i][j]表示s1[0,i]区间以及s2[0,j]区间内的所有子序列中,公共子序列的ASCII最大和

2.状态转移方程

3.初始化

不管是i=0,还是j=0,公共子序列都是空串,ASCII为0,即初始化为0

4.填表顺序    从上往下,从左往右

5.返回值       求出两个字符串的和sum,再减去2*dp[m][n]

具体代码:

int minimumDeleteSum(string s1, string s2) 
    {
        int m=s1.size(),n=s2.size();
        vector<vector<int>> dp(m+1,vector<int>(n+1));
        for(int i=1;i<=m;++i)
            for(int j=1;j<=n;++j)
            {
                dp[i][j]=max(dp[i-1][j],dp[i][j-1]);
                if(s1[i-1]==s2[j-1])
                    dp[i][j]=max(dp[i][j],dp[i-1][j-1]+s1[i-1]);
            }
        
        int sum=0;
        for(auto x:s1) sum+=x;
        for(auto x:s2) sum+=x;
        return sum-2*dp[m][n];
    }

 7.第七题

OJ传送门LeetCode<718>最长重复子数组

画图分析:

 对于本道题若继续采用以往的经验的话,因为求取的是连续的子数组,必须保证能跟在前面位置的后面,因此不能采用

1.状态表示

dp[i][j]表示:nums1中以i位置元素为结尾的所有子数组以及nums2中以j位置元素为结尾的所有子数组中,最长重复子数组的长度

2.状态转移方程

3.初始化

初始化第一行和第一列为0

4.填表顺序   从上往下填每一行

5.返回值    dp表中的最大值

具体代码:

int findLength(vector<int>& nums1, vector<int>& nums2) 
    {
        int m=nums1.size(),n=nums2.size();
        vector<vector<int>> dp(m+1,vector<int>(n+1));

        int ret=0;
        for(int i=1;i<=m;++i)
            for(int j=1;j<=n;++j)
                if(nums1[i-1]==nums2[j-1])
                    dp[i][j]=dp[i-1][j-1]+1,ret=max(ret,dp[i][j]);
        return ret;
    }

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2284694.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

浅析百度AOI数据与高德AOI数据的差异性

目录 前言 一、AOI属性数据 1、百度AOI数据 2、高德AOI数据 二、AOI矢量边界 1、百度AOI空间范围 2、高德AOI空间范围 三、数据获取频次和难易程度 1、接口限制 2、数据转换成本 四、总结 前言 在当今数字化时代&#xff0c;地理信息数据的精准性和丰富性对于城市规划…

白平衡与色温:摄影中的色彩密码

目录 一、色温&#xff1a;光线的色彩温度 &#xff08;一&#xff09;色温的定义与原理 &#xff08;二&#xff09;常见光源的色温 &#xff08;三&#xff09;相机色温与环境色温 二、白平衡&#xff1a;还原真实色彩的关键 &#xff08;一&#xff09;白平衡的定义与…

【Android】布局文件layout.xml文件使用控件属性android:layout_weight使布局较为美观,以RadioButton为例

目录 说明举例 说明 简单来说&#xff0c;android:layout_weight为当前控件按比例分配剩余空间。且单个控件该属性的具体数值不重要&#xff0c;而是多个控件的属性值之比发挥作用&#xff0c;例如有2个控件&#xff0c;各自的android:layout_weight的值设为0.5和0.5&#xff0…

深度学习|表示学习|卷积神经网络|参数共享是什么?|07

如是我闻&#xff1a; Parameter Sharing&#xff08;参数共享&#xff09;是卷积神经网络&#xff08;CNN&#xff09;的一个重要特性&#xff0c;帮助它高效地处理数据。参数共享的本质就是参数“本来也没有变过”。换句话说&#xff0c;在卷积层中&#xff0c;卷积核的参数&…

【25考研】人大计算机考研复试该怎么准备?有哪些注意事项?

人大毕竟是老牌985&#xff0c;复试难度不会太低&#xff01;建议同学认真复习&#xff01;没有机试还是轻松一些的&#xff01; 一、复试内容 由公告可见&#xff0c;复试包含笔试及面试&#xff0c;没有机试&#xff01; 二、参考书目 官方无给出参考书目&#xff0c;可参照…

国内优秀的FPGA设计公司主要分布在哪些城市?

近年来&#xff0c;国内FPGA行业发展迅速&#xff0c;随着5G通信、人工智能、大数据等新兴技术的崛起&#xff0c;FPGA设计企业的需求也迎来了爆发式增长。很多技术人才在求职时都会考虑城市的行业分布和发展潜力。因此&#xff0c;国内优秀的FPGA设计公司主要分布在哪些城市&a…

DeepSeek-R1:将强化学习用于激励大型语言模型的推理能力

目录 引言 一、DeepSeek-R1的贡献 二、DeepSeek-R1的方法 2.1、DeepSeek-R1-Zero&#xff1a;基础模型上的强化学习 2.2、DeepSeek-R1&#xff1a;冷启动强化学习 2.3、蒸馏&#xff1a;赋予小模型推理能力 三、DeepSeek-R1实验结果 3.1、模型优点 3.2、模型缺点 四、…

DPO、KTO、DiffusionDPO

DPO&#xff08;Direct Preference Optimization&#xff09; 原文来自于 https://arxiv.org/pdf/2305.18290&#xff0c; Bradley-Terry (BT)模型&#xff0c;假设人的喜欢遵循下面的公式&#xff0c;给定x&#xff0c;得到 y 1 y_1 y1​和 y 2 y_2 y2​分别遵循以下关系&am…

分享|instructionfine-tuning 指令微调是提高LLM性能和泛化能力的通用方法

《生成式AI导论》课程中&#xff0c;李宏毅老师提到一篇关于“ instruction fine-tuning” 指令微调的论文&#xff1a; 《Scaling Instruction-Finetuned Language Models》 摘要分享&#xff1a; 事实证明&#xff0c; 在一组以指令形式表达的数据集上微调语言模型可以提…

Mac Electron 应用签名(signature)和公证(notarization)

在MacOS 10.14.5之后&#xff0c;如果应用没有在苹果官方平台进行公证notarization(我们可以理解为安装包需要审核&#xff0c;来判断是否存在病毒)&#xff0c;那么就不能被安装。当然现在很多人的解决方案都是使用sudo spctl --master-disable&#xff0c;取消验证模式&#…

C++学习——认识和与C的区别

目录 前言 一、什么是C 二、C关键字 三、与C语言不同的地方 3.1头文件 四、命名空间 4.1命名空间的概念写法 4.2命名空间的访问 4.3命名空间的嵌套 4.4命名空间在实际中的几种写法 五、输入输出 5.1cout 5.2endl 5.3cin 总结 前言 开启新的篇章&#xff0c;这里…

基于Django的豆瓣影视剧推荐系统的设计与实现

【Django】基于Django的豆瓣影视剧推荐系统的设计与实现&#xff08;完整系统源码开发笔记详细部署教程&#xff09;✅ 目录 一、项目简介二、项目界面展示三、项目视频展示 一、项目简介 该系统采用了Python作为后端开发语言&#xff0c;采用Django作为后端架构&#xff0c;结…

Open FPV VTX开源之ardupilot双OSD配置摄像头

Open FPV VTX开源之ardupilot双OSD配置 1 源由2. 分析3. 配置4. 解决办法5. 参考资料 1 源由 鉴于笔者这台Mark4 Copter已经具备一定的历史&#xff0c;目前机载了两个FPV摄像头&#xff1a; 模拟摄像头数字摄像头(OpenIPC) 测试场景&#xff1a; 从稳定性的角度&#xff1…

【岛屿个数——BFS / DFS,“外海”】

题目 推荐阅读 AcWing 4959. 岛屿个数&#xff08;两种解法&#xff0c;通俗解释&#xff09; - AcWing 1.岛屿个数 - 蓝桥云课 (lanqiao.cn) 代码 #include <bits/stdc.h> using namespace std; #define x first #define y second int dx4[4] {-1, 0, 1, 0}, dy4[4] …

《STL基础之vector、list、deque》

【vector、list、deque导读】vector、list、deque这三种序列式的容器&#xff0c;算是比较的基础容器&#xff0c;也是大家在日常开发中常用到的容器&#xff0c;因为底层用到的数据结构比较简单&#xff0c;笔者就将他们三者放到一起做下对比分析&#xff0c;介绍下基本用法&a…

基于Flask的豆瓣电影可视化系统的设计与实现

【FLask】基于Flask的豆瓣电影可视化系统的设计与实现&#xff08;完整系统源码开发笔记详细部署教程&#xff09;✅ 目录 一、项目简介二、项目界面展示三、项目视频展示 一、项目简介 随着互联网技术的飞速发展&#xff0c;影视剧行业的数据量呈爆炸性增长&#xff0c;其中影…

LosslessScaling-学习版[steam价值30元的游戏无损放大/补帧工具]

LosslessScaling 链接&#xff1a;https://pan.xunlei.com/s/VOHc-yZBgwBOoqtdZAv114ZTA1?pwdxiih# 解压后运行"A-绿化-解压后运行我.cmd"

【JS|第28期】new Event():前端事件处理的利器

日期&#xff1a;2025年1月24日 作者&#xff1a;Commas 签名&#xff1a;(ง •_•)ง 积跬步以致千里,积小流以成江海…… 注释&#xff1a;如果您觉得有所帮助&#xff0c;帮忙点个赞&#xff0c;也可以关注我&#xff0c;我们一起成长&#xff1b;如果有不对的地方&#xf…

Blazor-Blazor Web App项目结构

让我们还是从创建项目开始&#xff0c;来一起了解下Blazor Web App的项目情况 创建项目 呈现方式 这里我们可以看到需要选择项目的呈现方式&#xff0c;有以上四种呈现方式 ● WebAssembly ● Server ● Auto(Server and WebAssembly) ● None 纯静态界面静态SSR呈现方式 WebAs…

观察者模式和订阅发布模式

有人把观察者模式等同于发布订阅模式&#xff0c;也有人认为这两种模式存在差异&#xff0c;本质上就是调度的方法不同。 相比较&#xff0c;发布订阅将发布者和观察者之间解耦。&#xff08;发布订阅有调度中心处理&#xff09;