最长公共上升子序列(LCIS)

2023-11-17

前置知识

  1. LCS
    在这里插入图片描述

  2. LIS

注意:

  刚开始看这个问题的时候,第一反应是先求出LCS再求出LCS的LIS,事实上这是有问题的,我们并不能保证这么求出的LCIS是最长的,比如下面这个例子

Example
a:7 1 5 6 4 2 7
b:7 1 5 4 6 7 2
按照递归的取“最长公共子序列”,取出:
7 1 5 6 2
此序列的“最长上升子序列”为:
1 5 6 (len=3)
但原序列的“最长公共上升子序列”为:
1 5 6 7 (len=4)

求解

 设第一个串为a,第二个串为b

  1. 首先确定dp状态f[i, j],表示前a串前i个字符和b串前j个字符且以b[j]为结尾的LCIS
  2. 状态方程:
    对于当处于(a[i], b[j]) 状态时 ,由于dp状态就决定了,b[j]是一定作为这个状态下LICS的结尾的,所以对于a[i],就有两种情况,将其纳入LCIS或者不纳入,首先先说不讲a[i]纳入LCIS的情况
    (1)若是 a[i] != b[j] ,显然是一定不能讲a[i]与b[j]进行配对的,那么问题就缩小成了前a的前i - 1个字符与b的前j个字符且以b[j]结尾的LCIS,即f[i - 1, j]也就是说 ,i之前的以b[j]结尾的序列自然没有改变,仍然是长度仍然是f[i−1][j]; 若是a[i] == b[i] 如果不想要a[i]与b[j]进行配对,是不是也会得到上面的结果,故当
    不讲a[i]与b[j]配对(或无法配对)时,f[i, j] = f[i - 1, j]

(2)当a[i] == b[j]且它们进行配对时,就要在a串前i - 1个字符和b的前j - 1个字符中找到一个最长的序列,设这个序列以t结尾且b[t] < b[j],是不是就等价于
f[i, j] = max(f[i - 1, t]) + 1 (t > 0 && t < j && b[t] < b[j])

这样就把这个问题可以转化为最优子结构的问题,且得到状态转移方程如下

				f[i - 1, j]    (a[i] != b[j])
f[i, j] = 
				max(f[i - 1, t]) + 1   (t > 0 && t < j && b[t] < b[j]) (a[i] == b[j])

讲上述思路转化为代码

for (int i = 1; i <= n; i ++ )
{
    for (int j = 1; j <= n; j ++ )
    {
        f[i][j] = f[i - 1][j];
        if (a[i] == b[j])
        {
            int maxv = 1;
            for (int k = 1; k < j; k ++ )
                if (b[j] > b[k])
                    maxv = max(maxv, f[i - 1][k] + 1);
            f[i][j] = max(f[i][j], maxv);
        }
    }
}

 上面代码的时间复杂度为O(n 3),是很不理想的,可以对其进行等价转化为O(n 2)的优化
观察第三层循环,可以发现每次循环求得的maxv是满足a[i] > b[k]的f[i - 1][k] + 1的前缀最大值。,而且是在a[i] == b[j]的时候成立,且可以发现,在每一次进行第二层循环时,a[i]是不变的,这也就可以推出,与a[i]进行配对的b[j]的值也是暂时不变的,那么把b[j]等价转化为a[i],并将maxv提至第一层循环内,在每一次比较a[i]和b[j]时,一起讲maxv处理出来,这样就可以将其优化为如下的O(n 2)的代码

for (int i = 1; i <= n; i++) {
        int maxv = 0;
        for (int j = 1; j <= n; j++) {
            f[i][j] = f[i - 1][j];
            if (a[i] == b[j]) f[i][j] = max(f[i][j], maxv + 1);
            if (a[i] > b[j]) maxv = max(maxv, f[i - 1][j]);        
        }
}

这样其实已经够了,但是追求优化的话,还可以进行空间的优化,不难发现,每一次都止利用了上一层的结果,那么可以采用滚动数组的方法进行空间优化

for (int i = 1; i <= n; i++) {
        int maxv = 0;
        for (int j = 1; j <= n; j++) {
            if (a[i] == b[j]) f[j] = max(f[j], maxv + 1);
            if (a[i] > b[j]) maxv = max(maxv, f[j]);        
        }
    }

acwing 272 最长公共上升子序列

#include <iostream>

using namespace std;

const int maxn = 3e3 + 5;

int f[maxn], a[maxn], b[maxn];
int n, ans;

int main()
{
    cin >> n;
    for (int i = 1; i <= n; i++) cin >> a[i];
    for (int i = 1; i <= n; i++) cin >> b[i];
    for (int i = 1; i <= n; i++) {
        int maxv = 0;
        for (int j = 1; j <= n; j++) {
            if (a[i] == b[j]) f[j] = max(f[j], maxv + 1);
            if (a[i] > b[j]) maxv = max(maxv, f[j]);        
            ans = max(f[j], ans);
        }
    }
    cout << ans << endl;
    return 0;
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

最长公共上升子序列(LCIS) 的相关文章

  • 检测到 NuGet 包的版本冲突

    我正在开发 ASP Net core 2 1 Web 应用程序项目 我的解决方案中有 1 个项目和 3 个其他库 它是高级架构 数据访问层 DAL 业务层 BL 公共层 CL 所以我需要添加引用来连接一些库和项目 我已经添加了CL参考我的项
  • GCC C++ (ARM) 和指向结构体字段的 const 指针

    假设有一个简单的测试代码 typedef struct int first int second int third type t define ADDRESS 0x12345678 define REGISTER type t ADDRE
  • 将处理后的图形绘制到另一个图形中

    我想将一个经过处理的图形绘制到另一个图形中 I have two graphics var gHead Graphics FromImage h var gBackground Graphics FromImage b Transform
  • MEX 文件中的断言导致 Matlab 崩溃

    我正在使用mxAssert 宏定义为matrix h在我的 C 代码中 mex 可以完美编译 当我调用的 mex 代码中违反断言时 该断言不会导致我的程序崩溃 而是导致 Matlab 本身崩溃 我错过了什么吗 这是有意的行为吗 当我查看 M
  • 在 C++ 中分割大文件

    我正在尝试编写一个程序 该程序接受一个大文件 任何类型 并将其分成许多较小的 块 我想我已经有了基本的想法 但由于某种原因我无法创建超过 12 kb 的块大小 我知道谷歌等上有一些解决方案 但我更感兴趣的是了解这个限制的根源是什么 然后实际
  • 在 OpenCL 中将函数作为参数传递

    是否可以在 OpenCL 1 2 中将函数指针传递给内核 我知道可以用C实现 但不知道如何在OpenCL的C中实现 编辑 我想做这篇文章中描述的同样的事情 在 C 中如何将函数作为参数传递 https stackoverflow com q
  • 捕获 foreach 条件中抛出的异常

    我有一个foreach在 foreach 本身的条件下循环期间中断的循环 有没有办法try catch抛出异常然后继续循环的项 这将运行几次 直到异常发生然后结束 try foreach b in bees exception is in
  • 处理 fanart.tv Web 服务响应 JSON 和 C#

    我正在尝试使用 fanart tv Webservice API 但有几个问题 我正在使用 Json Net Newtonsoft Json 并通过其他 Web 服务将 JSON 响应直接反序列化为 C 对象 这里的问题是元素名称正在更改
  • 在 Xcode4 中使用 Boost

    有人设置 C Xcode4 项目来使用 Boost 吗 对于一个简单的 C 控制台应用程序 我需要在 Xcode 中设置哪些设置 Thanks 用这个来管理它 和这个
  • 在 C# 中将位从 ulong 复制到 long

    所以看来 NET 性能计数器类型 http msdn microsoft com en us library system diagnostics performancecounter aspx有一个恼人的问题 它暴露了long对于计数器
  • 转到 C# WPF 中的第一页

    我正在 WPF 中使用导航服务 为了导航到页面 我使用 this NavigationService Navigate new MyPage 为了返回我使用 this NavigationService GoBack 但是如何在不使用的情况
  • Qt - 设置不可编辑的QComboBox的显示文本

    我想将 QComboBox 的文本设置为某些自定义文本 不在 QComboBox 的列表中 而不将此文本添加为 QComboBox 的项目 此行为可以在可编辑的 QComboBox 上实现QComboBox setEditText cons
  • 32位PPC rlwinm指令

    我在理解上有点困难rlwinmPPC 汇编指令 旋转左字立即然后与掩码 我正在尝试反转函数的这一部分 rlwinm r3 r3 0 28 28 我已经知道什么了r3 is r3在本例中是一个 4 字节整数 但我不确定这条指令到底是什么rlw
  • 如何检测 C# 中该字典键是否存在?

    我正在使用 Exchange Web 服务托管 API 和联系人数据 我有以下代码 即功能性的 但并不理想 foreach Contact c in contactList string openItemUrl https service
  • 我应该在应用程序退出之前运行 Dispose 吗?

    我应该在应用程序退出之前运行 Dispose 吗 例如 我创建了许多对象 其中一些对象具有事件订阅 var myObject new MyClass myObject OnEvent OnEventHandle 例如 在我的工作中 我应该使
  • 如何查明CONFIG_FANOTIFY_ACCESS_PERMISSIONS是否启用?

    我想利用fanotify 7 http man7 org linux man pages man7 fanotify 7 html我遇到的问题是在某些内核上CONFIG FANOTIFY ACCESS PERMISSIONS不起作用 虽然C
  • 在基类集合上调用派生方法

    我有一个名为 A 的抽象类 以及实现 A 的其他类 B C D E 我的派生类持有不同类型的值 我还有一个 A 对象的列表 abstract class A class B class A public int val get privat
  • Swagger 为 ASP.CORE 3 中的字典生成错误的 URL

    当从查询字符串中提取的模型将字典作为其属性之一时 Swagger 会生成不正确的 URL 如何告诉 Swagger 更改 URL 中字典的格式或手动定义输入参数模式而不自动生成 尝试使用 Swashbuckle 和 NSwag 控制器 pu
  • 从类模板参数为 asm 生成唯一的字符串文字

    我有一个非常特殊的情况 我需要为类模板中声明的变量生成唯一的汇编程序名称 我需要该名称对于类模板的每个实例都是唯一的 并且我需要将其传递给asm关键字 see here https gcc gnu org onlinedocs gcc 12
  • 如何创建向后兼容 Windows 7 的缩放和尺寸更改每显示器 DPI 感知应用程序?

    我是 WPF 和 DPI 感知 API 的新手 正在编写一个在 Windows 7 8 1 和 10 中运行的应用程序 我使用具有不同每个显示器 DPI 设置的多个显示器 并且有兴趣将我的应用程序制作为跨桌面配置尽可能兼容 我已经知道可以将

随机推荐

  • 网络编程——TCP并发服务器模型

    1 多线程中的newfd 能否修改成全局 不行 为什么 因为如果是全局变量 文件描述符就是唯一的 所有的客户端都会在同一个文件描述符通信 2 多线程中分支线程的newfd能否不另存 直接用指针间接访问主线程中的newfd 不行 为什么 如果
  • 微信小程序-仿智行火车票12306

    微信小程序 仿智行火车票12306 微信小程序 仿智行火车票12306 主页有轮播图 有导航栏 有个人中心 可以实现火车票 飞机票 汽车票的选择 适合初学者学习 下面是示例图片 下载链接 https download csdn net do
  • Linux系统图形界面和命令行界面之间的切换

    一 系统不在虚拟机中的情况 使用ctrl alt F1 6切换到命令行界面 ctrl alt F7切换到图形界面 二 系统在虚拟机中的情况 Ctrl Alt shift F1 6切换到命令行界面 使用Alt F7返回到图形界面 注 以上方法
  • hashmap中为什么使用红黑树?

    在回答这个问题之前 我们先了解一下有关二叉树的基本内容 二叉排序树 又称二叉查找树 1 若左子树不为空 则左子树上所有结点的值均小于根结点的值 2 若右子树不为空 则右子树上所有结点的值均大于根节点的值 3 左右子树也为二叉排序树 平衡二叉
  • 2017 ICCV之语义分割:Cascaded Feature Network for Semantic Segmentation of RGB-D Images

    Cascaded Feature Network for Semantic Segmentation of RGB D Images 目前的问题 1 为了计算对象 场景关系的表示 最近大量的分割网络使用一组感受野来丰富卷积特征的文本信息 这
  • book_read_link

    结构性改革 黄奇帆 微信读书 分析与思考 黄奇帆的复旦经济课 黄奇帆 微信读书
  • java通过web3j获取ETH交易明细

    我们在项目里面如果想要得到用户的ETH交易明细怎么做呢 有两种方式 1 直接获取ETH最新块的交易明细 2 通过块获取用户的交易明细 废话不多说 直接贴代码看了 package com example demo web3jLog impor
  • pdf.js引入方式及初始化配置

    官方下载地址 Getting StartedA general purpose web standards based platform for parsing and rendering PDFs http mozilla github
  • actuator--基础--04--Springboot集成

    actuator 基础 04 Springboot集成 代码位置 https gitee com DanShenGuiZu learnDemo tree master actuator learn actuator01 1 代码 1 1 依
  • MongoDB游标

    数据库会使用游标返回 find 的执行结果 游标的客户端实现通常能够在很大程度上对查询的最终输出进行控制 你可以限制结果的数量 跳过一些结果 按任意方向的任意键组合对结果进行排序 以及执行许多其他功能强大的操作 要使用 shell 创建游标
  • 爬虫实战之华为应用市场

    目录 一 需求说明 二 步骤 1 检查当前页面的URL所获得的响应的数据 笨办法 程序验证 不建议 简单办法 抓包 验证 抓包 推荐 动态加载验证 查找页面的信息 2 获取排行页面数据 操作 源码 信息解析 3 详情页面分析 寻找URL 验
  • leetcode 577

    给定一个字符串 s 你需要反转字符串中每个单词的字符顺序 同时仍保留空格和单词的初始顺序 示例 1 输入 s Let s take LeetCode contest 输出 s teL ekat edoCteeL tsetnoc 示例 2 输
  • C++中的强引用与弱引用

    https juejin cn post 7102838307062546445 1 weak ptr的原理 weak ptr 是为了配合 shared ptr 而引入的一种智能指针 它指向一个由 shared ptr 管理的对象而不影响所
  • 神经网络中的激活函数

    一 激活的概念 将输入映射为特定分布的输出 完成非线性变换 多细胞生物神经元的树突接收信息 触发区整合电位 产生神经冲动 末端的突触向下一个神经元传递刺激 以人脑为例 人脑的细胞受刺激产生活动 而刺激的强度需要达到一定的阈值 没有达到阈值的
  • 基于51单片机数字频率计的设计与实现

    目录 第一章 系统原理与总体设计 1 1系统组成 1 2系统原理 1 3测量原理 1 4频率测量与总体设计 第二章 硬件电路设计 2 1硬件电路框图 2 2数字频率计原理图 2 3硬件电路设计 第三章 软件程序设计 3 1程序流程图 3 2
  • 魔方机器人之下位机编程------下位机完整程序

    头文件包含 include Includes h 总头文件 在此添加全局变量定义 uint8 msg 14 Hello World void PWM Init void PWM0 上侧旋转舵机 PWME PWME0 0x00 Disable
  • 查找恢复密钥

    登陆自己的微软账号可查看恢复密钥 点击以下链接查找恢复密钥 https account microsoft com devices recoverykey 根据密钥ID 输入对应的恢复密钥
  • win10蓝牙无法连接,可以尝试在此Windows设备上打开蓝牙

    win10蓝牙无法连接 可以尝试在此Windows设备上打开蓝牙 笔记本右下角蓝牙图标消失不见 操作步骤 1 首先在打开电脑中 按下 Win R 打开运行窗口输入 services msc 并进入 2 2 打开服务列表后 不断的向下翻 找到
  • 【华为OD机试真题】对称字符串(python)100%通过率 超详细代码注释 代码解读

    华为OD机试真题 2022 2023 真题目录 点这里 华为OD机试真题 信号发射和接收 试读 点这里 华为OD机试真题 租车骑绿道 试读 点这里 对称字符串 时间限制 1s空间限制 256MB限定语言 不限 题目描述 对称就是最大的美学
  • 最长公共上升子序列(LCIS)

    前置知识 LCS LIS 注意 刚开始看这个问题的时候 第一反应是先求出LCS再求出LCS的LIS 事实上这是有问题的 我们并不能保证这么求出的LCIS是最长的 比如下面这个例子 Example a 7 1 5 6 4 2 7 b 7 1