【动态规划】两个数组问题

news2024/11/24 2:14:47

文章目录

  • 动态规划(两个数组问题)
    • 1. 最长公共子序列
    • 2. 不相交的线
    • 3. 不同的子序列
    • 4. 交错字符串
    • 5. 两个字符串的最小ASCII和
    • 6. 最长重复子数组
    • 7. 通配符匹配

动态规划(两个数组问题)

1. 最长公共子序列

题目链接

  1. 状态表示

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

  2. 状态转移方程

    根据最后一个位置的请款分类讨论。

    z5uwarw27c-1692105710163.png

  3. 初始化

    关于字符串的dp问题,空串是有研究意义的。引入空串的概念之后会方便我们的初始化

    这里还可以使用之前的方法,使用辅助节点的方式

  4. 填表顺序

    从下往上,从左到右

  5. 返回值

AC代码:

class Solution 
{
public:
    int longestCommonSubsequence(string text1, string text2) 
    {
        int n = text1.size();
        int m = text2.size();
        vector<vector<int>> dp(n + 1, vector<int>(m + 1));
        for (int i = 1; i <= n; i++)
        {
            for (int j = 1; j <= m; j++)
            {
                if (text1[i - 1] == text2[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[n][m];
    }
};

2. 不相交的线

题目链接

题目分析:根据这个题目可以看到不就是找最长公共子序列嘛

  1. 状态表示

    dp[i][j] 表示 0 到 i 的所有子序列以及 0 到 j 的所有子序列当中,最长的公共子序列

  2. 状态转移方程

    z5uwarw27c-1692105710163.png

  3. 初始化

  4. 填表

  5. 返回值

AC代码:

class Solution 
{
public:
    int maxUncrossedLines(vector<int>& nums1, vector<int>& nums2) 
    {
        int n = nums1.size();
        int m = nums2.size();
        vector<vector<int>> dp(n + 1, vector<int>(m + 1));
        for (int i = 1; i <= n; i++)
        {
            for (int j = 1; j <= m; 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[n][m];
    }
};

3. 不同的子序列

题目链接

  1. 状态表示

    dp[i][j] 表示 0 到 j 之间的所有子序列中有多少个出现 目标中0 到 i 之间的字母

  2. 状态转移方程

    wwbqeo8ik2-1692159834158.png

  3. 初始化

  4. 填表

  5. 返回值

AC代码:

class Solution 
{
public:
    int numDistinct(string s, string t) 
    {
        int n = s.size();
        int m = t.size();
        vector<vector<double>> dp(m + 1, vector<double>(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 (s[j - 1] == t[i - 1]) dp[i][j] += dp[i - 1][j - 1];
            }
        }
        return dp[m][n];
    }
};

4. 交错字符串

题目链接

  1. 状态表示

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

  2. 状态转移方程

    6bav0zoena-1692234012162.png

  3. 初始化

    当两个字符串都是空的时候,返回的一定是true,当s1 不为空, s2 为空,只要s1有一个不等于s3则直接返回false否则为true

    s2的初始化也一样

  4. 填表

    从上到下,从左到右

  5. 返回值

AC代码:

class Solution 
{
public:
    bool isInterleave(string s1, string s2, string s3) 
    {
        int m = s1.size();
        int 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++)
            {
                if ((s1[i] == s3[i + j] && dp[i - 1][j]) || (s2[j] == s3[i + j] && dp[i][j - 1]))
                    dp[i][j] = true;
            }
        }
        return dp[m][n];
    }
};

5. 两个字符串的最小ASCII和

题目链接

  1. 状态表示

    分析,这个题目要找两个字符串最小的,可以找到公共最大的然后反向求

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

  2. 状态转移方程

    vd6lhlh6jm-1692235583156.png

  3. 初始化

    无需初始化

  4. 填表

    从左到右,从上到下

  5. 返回值

    两个字符串的和前去最大的乘以2

AC代码:

class Solution 
{
public:
    int minimumDeleteSum(string s1, string s2) 
    {
        int m = s1.size();
        int 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][j - 1], dp[i - 1][j]);
                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 e : s1) sum += e;
        for (auto e : s2) sum += e;
        return sum - dp[m][n] - dp[m][n];
    }
};

6. 最长重复子数组

题目链接

  1. 状态表示

    dp[i][j]以 i 位置为结尾的所有子数组,以及以j 位置为结尾的所有子数组当中,最长公共子数组的长度

  2. 状态转移方程

    1n7eel8afo-1692236963060.png

  3. 初始化

    无需初初始化

  4. 填表

  5. 返回值

AC代码:

class Solution 
{
public:
    int findLength(vector<int>& nums1, vector<int>& nums2) 
    {
        int m = nums1.size();
        int 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;
    }
};

7. 通配符匹配

题目链接

  1. 状态表示

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

  2. 状态转移方程

    le1zm27ois-1692322359180.png

    这种有很多表示方法的状态转移方程,需要优化不可能把每个状态都表示出来

    第一种就是采用数学方法来优化:

    image-20230818093607316

    还可以根据状态表示以及实际情况优化状态转移方程

    ok3jt4o0a6-1692322740156.png

  3. 初始化

    p[0][j] == ”*“ 时就一直是true

  4. 填表

  5. 返回值

AC代码:

class Solution 
{
public:
    bool isMatch(string s, string p) 
    {
        int m = s.size();
        int n = p.size();
        s = " " + s, p = " " + p;
        vector<vector<bool>> dp(m + 1, vector<bool>(n + 1));
        dp[0][0] = true;
        for (int j = 1; j <= n; j++)
        {
            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- 1][j] || dp[i][j - 1];
                else if (p[j] == '?') dp[i][j] = dp[i - 1][j - 1];
                else 
                {
                    if (s[i] == p[j]) dp[i][j] = dp[i - 1][j - 1];
                }
            }
        }
        return dp[m][n];
    }
};
   {
            if (p[j] == '*') 
                dp[i][j] = dp[i- 1][j] || dp[i][j - 1];
            else if (p[j] == '?') dp[i][j] = dp[i - 1][j - 1];
            else 
            {
                if (s[i] == p[j]) dp[i][j] = dp[i - 1][j - 1];
            }
        }
    }
    return dp[m][n];
}

};


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

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

相关文章

爬虫小白也能玩转!Python爬虫中的异常处理与网络请求优化

大家好&#xff0c;我是来自爬虫世界的小编。今天&#xff0c;我要和大家分享一些关于Python爬虫中的异常处理和网络请求优化的经验。不论你是初学者还是有一定经验的爬虫程序员&#xff0c;我相信这些实用的技巧和代码示例都能为你在爬取数据的过程中带来方便和效率。 1.异常…

广告牌安全传感器,实时监测事故隐患尽在掌握

在现代城市中&#xff0c;广告牌作为商业宣传的重要媒介&#xff0c;已然成为城市中一道独特的风景线。然而&#xff0c;随着城市迅速发展&#xff0c;广告牌的安全问题也引起了大众关注。广告招牌一般悬挂于建筑物高处&#xff0c;量大面大。由于设计、材料、施工方法的缺陷&a…

VC2019调用pngquantDLL示例源码

pngquantDLL是大名鼎鼎的PNG图片压缩命令行程序pngquant的源码编译的一个DLL库文件&#xff0c;主要是方便第三方程序集成使用&#xff1b; pngquant是一个命令行实用程序和一个用于有损压缩PNG图像的库。 这种转换大大减少了文件大小(通常高达70%)&#xff0c;并保持了alpha透…

相机的位姿在地固坐标系ECEF和ENU坐标系的转换

在地球科学和导航领域&#xff0c;通常使用地心地固坐标系&#xff08;ECEF&#xff0c;Earth-Centered, Earth-Fixed&#xff09;和东北天坐标系&#xff08;ENU&#xff0c;East-North-Up&#xff09;来描述地球上的位置和姿态。如下图所示&#xff1a; ​地心地固坐标ecef和…

fastapi系列1-基础知识

学习资料 官网&#xff1a;https://fastapi.tiangolo.com/ github:https://github.com/tiangolo/fastapi 视频教程【独家新技术】从0到1学习 FastAPI 框架的所有知识点 依赖底层包&#xff1a;https://www.starlette.io/ 轻松上手Python的Web神器&#xff1a;FastAPI教程&…

ubuntu20.04共享文件夹—— /mnt/hgfs里没有共享文件夹

参考文章&#xff1a;https://blog.csdn.net/Edwinwzy/article/details/129580636 虚拟机启用共享文件夹后&#xff0c;/mnt/hgfs下面为空&#xff0c;使用 vmware-hgfsclient 查看设置的共享文件夹名字也是为空。 解决方法&#xff1a; 1. 重新安装vmware tools. 在菜单…

HarmonyOS/OpenHarmony应用开发-ArkTS语言渲染控制ForEach循环渲染

ForEach基于数组类型数据执行循环渲染。说明&#xff0c;从API version 9开始&#xff0c;该接口支持在ArkTS卡片中使用。 一、接口描述 ForEach(arr: any[], itemGenerator: (item: any, index?: number) > void,keyGenerator?: (item: any, index?: number) > stri…

谈谈IP地址和子网掩码的概念及应用

个人主页&#xff1a;insist--个人主页​​​​​​ 本文专栏&#xff1a;网络基础——带你走进网络世界 本专栏会持续更新网络基础知识&#xff0c;希望大家多多支持&#xff0c;让我们一起探索这个神奇而广阔的网络世界。 目录 一、IP地址的概念 二、IP地址的分类 1、A类 …

react之 router6路由 (两种路由模式、两种路由跳转、两种传参与接收参数、嵌套路由,layout组件、路由懒加载)

目录 react路由1&#xff1a;安装和两种模式react路由2&#xff1a;两种路由跳转 &#xff08; 命令式与编程式&#xff09;2-1 路由跳转-命令式2-2 路由跳转-编程式 - 函数组件2-2-1 app.jsx2-2-2 page / Home.jsx2-2-3 page / About.jsx2-2-4 效果 react路由3&#xff1a;函数…

恒运资本:A股质押降至十年新低,高比例质押公司不足1%!

2018年&#xff0c;A股商场股权质押规划到达历史高位&#xff0c;为化解危险&#xff0c;监管层通过多种方式、多方合力给予纾解&#xff0c;取得积极成效。上篇分析了A股质押危险大幅缓解的六大原因&#xff0c;本篇从高份额质押股特征、职业、地域、企业类型等视点&#xff0…

七麦analysis参数加密分析

文章目录 1. 接口分析2. 断点调式3. 补环境重写加密4. 验证结果 1. 接口分析 目标站点&#xff1a; aHR0cHM6Ly93d3cucWltYWkuY24vcmFuay9tYXJrZXRSYW5r 先刷新网页&#xff0c;请求接口中的analysis参数本次分析的目标 2. 断点调式 打上XHR断点&#xff0c;刷新页面之后断点…

【MT32F006】MT32F006之串口

本文最后修改时间&#xff1a;2023年03月30日 一、本节简介 本文介绍如何使用MT32F006的串口。 二、实验平台 库版本&#xff1a;V1.0.0 编译软件&#xff1a;MDK5.37 硬件平台&#xff1a;MT32F006开发板&#xff08;主芯片MT32F006&#xff09; 仿真器&#xff1a;JLINK…

无涯教程-Perl - umask函数

描述 此函数为当前进程设置umask(创建文件和目录时应用的默认掩码)。 EXPR的值必须是八进制数。如果省略EXPR,则只需返回先前的值。 语法 以下是此函数的简单语法- umask EXPRumask返回值 此函数返回先前的umask值。 例 以下是显示其基本用法的示例代码- #!/usr/bin/pe…

Java学习笔记30——字节缓冲流

字节缓冲流 字节缓冲流缓冲输出流缓冲输入流 复制视频速度对比 字节缓冲流 缓冲输出流 BufferadOutputStream通过设置这样的输出流&#xff0c;应用程序可以向底层输出流写入字节&#xff0c;而不必为写入的每个细节导致底层系统的调用 构造方法 BufferadOutputStream(Outpu…

【Elsevier旗下】1区SCI,5天见刊!稳定检索36年

近日国自然即将发布&#xff0c;想必申请过国自然基金作者都知道&#xff0c;需要有研究基础&#xff0c;说白了就是需要有文章支持。那么稿子写好了&#xff0c;选择一本靠谱优质期刊也是一门学问。 以下2本Elsevier 旗下审稿快刊&#xff0c;各项指标优秀&#xff0c;实为评…

QT connect使用简单介绍

如图&#xff0c;首先 connect是线程安全的。其次它有很多重载&#xff0c;当然最重要的还是QT4连接和QT5连接的区别&#xff0c;这个函数重载表示connect函数也是支持lambda函数的。 connect(const QObject *sender, PointerToMemberFunction signal, Functor functor)connec…

Redis——set类型详解

概要 Set&#xff08;集合&#xff09;&#xff0c;将一些有关联的数据放到一起&#xff0c;集合中的元素是无序的&#xff0c;并且集合中的元素是不能重复的 之前介绍的list就是有序的&#xff0c;对于列表来说[1, 2, 3] 和 [2, 1, 3]是两个不同的列表&#xff0c;而对于集合…

阿里Canal学习笔记

github地址 canal 使用IDEA打开&#xff0c;注意国内加载慢的问题&#xff0c;解决方式如下&#xff1a; <?xml version"1.0" encoding"UTF-8"?> <settings xmlns"http://maven.apache.org/SETTINGS/1.0.0"xmlns:xsi"http://w…

CAS:2143933-81-5,ICG-Maleimide,吲哚菁绿马来酰亚胺,脂溶性染料试剂

今日文章关键词&#xff1a;脂溶性染料试剂,吲哚菁绿马来酰亚胺&#xff0c;CAS&#xff1a;2143933-81-5 试剂基团反应特点&#xff1a;ICG-maleimide的马来酰 亚胺可以和蛋白、多肽、小分子或抗体上的SH巯基反应连接。ICG染料的马来酰亚胺提供了开发共轭物的机会。Maleimide…

Python入门【原生字符串、边界字符、search函数、re模块中其他常用的函数 、贪婪模式和非贪婪模式、择一匹配(|)的使用、分组】(三十)

&#x1f44f;作者简介&#xff1a;大家好&#xff0c;我是爱敲代码的小王&#xff0c;CSDN博客博主,Python小白 &#x1f4d5;系列专栏&#xff1a;python入门到实战、Python爬虫开发、Python办公自动化、Python数据分析、Python前后端开发 &#x1f4e7;如果文章知识点有错误…