练习题(动态规划)

news2024/12/28 22:38:00

一,最长上升子序列2

题目:

思路分析:

之前的最长上升子序列的时间度是O(n^2),同时集合划分是按以第 i - 1 个数是几来划分的,状态转移方程也很简单是 f[i] = f[j] + 1  ,最后取所有一个max

那怎么优化呢?考虑一个每次求的时候有没有冗余

例如:3 1 2 1 8 5 6

如果一个数能接在3后面,那一定可以接在1后面,对吧,那1就比这个3好,所以如果我们能接在以一个大点的数结尾的上升子序列后面,那就一定可以接在以一个小一点的数结尾的上升子序列后面,以此为启发   我们可以存储前面每种长度的最长上升子序列的结尾的最小值是多少,我们可以存到数组里面去。

我们可以猜测一下,随着上升子序列的长度的增加,子序列结尾的数一定是严格单调递增的,

假如长度为6的上升子序列的结尾最小值是a1,长度为5的子序列的结尾最小值是a2,如果a1小于 a2 ,那么我们一定可以从长度为6的子序列里面截取一个长度是5的最长上升子序列,并且结尾小于a2,那么长度为5的上升子序列的结尾就一定不是a2。

这样就矛盾了,所以整个序列一定是严格单调递增的。

假设,我们想求一下当前这个数 ai,以ai结尾的最长子序列,那我们要从序列里找到一个最大的小于ai的序列,假设长度为4的上升子序列的最小结尾值是q4,q4是最大的小于等于ai的数,那把ai接过去,那这样我们就得到了一个以ai结尾的长度为5的上升子序列,假设长度为5的上升子序列的最小结尾是q5,由于q4是最大的小于等于ai的,那么q5就是大于等于ai的,所以ai一定不可能接到长度是5的子序列后面,因此,以ai结尾的上升子序列的最大长度就是5,那如何找到最大的小于等于ai的数呢?可以用二分O(logn)。然后更新一下q5,变成ai。因为找到了新的长度是5的上升子序列的最小结尾。

一共n个数,二分logn,那么一共 O(n*logn)

代码:

#include <iostream>
#include <algorithm>

using namespace std;

const int N = 100010;

int n;
int a[N];
int q[N];  //  存储所有不同长度的上升子序列的结尾的最小值


int main()
{
    cin >> n;
    for (int i = 0; i < n; i ++ ) cin >> a[i];
    
    int len = 0;  //  初始化最长上升子序列的长度
    q[0] = -2e9;  //  初始化 q[0] 为一个小于所有数组元素的值,方便后续比较
    for (int i = 0; i < n; i ++ )  //  遍历每个数
    {   
        int l = 0, r = len;  //  二分查找那个最大的小于等于ai的数
        while (l < r)
        {
            int mid = l + r + 1 >> 1;
            if (q[mid] < a[i]) l = mid;  
            else r = mid - 1;
        }
        len = max(len, r + 1);  // 更新最长上升子序列的长度
        q[r + 1] = a[i];  //  更新结尾最小值

    }
    
    cout << len << endl;
}

二,最短编辑距离

题目:

思路:

依旧是dp的思路框,dp为什么快呢,他就是对暴搜的优化,可以用一个数来表示一堆东西

这里是按最后一步是删除,增加还是改变来分的,,假如是删除,那应该是把 a 的1到i - 1跟b的1到 j 匹配,再删除ai,这样才一样,所以第一类的最小值应该是 f[i - 1, j ] + 1。假如是增加一个字母,添加完后两字符串相等,那其实就说明在添加之前,a的 1 到 i 已经和 b 的 1 到 j - 1 匹配了,然后添加一个之后,两字符串相等,那第二类的最小值赢是 f[i, j - 1] + 1。假如是改,改完之后相等了,那改之前应该是 a 的前 i - 1个字母和 b的j -  1的字母匹配上,如果a[i] != b[j] 那就加一步改,如果相等了,那就不加了,所以第三类是 f[i - 1, j - 1] + 1/0(1或者0);

综上 f[i, j] = min(f[i - 1, j] +1, f[i, j - 1] + 1, f[i - 1, j - 1] + 1/0) ,这就是这个题的状态转移方程;

代码:

#include <iostream>
#include <algorithm>

using namespace std;

const int N = 1010;

int n, m;
char a[N], b[N];
int f[N][N];

int main()
{
    cin >> n >> a + 1;
    cin >> m >> b + 1;
    
    //  初始化
    for (int i = 0; i <= m; i ++ ) f[0][i] = i;  // 将空字符串转换为 b 的前 i 个字符需要 i 次插入操作
    for (int i = 0; i <= n; i ++ ) f[i][0] = i;  // 将 a 的前 i 个字符转换为空字符串需要 i 次删除操作
    
    //  dp
    for (int i = 1; i <= n; i ++ )
        for (int j = 1; j <= m ; j ++ )
        {  //  用方程
            f[i][j] = min(f[i - 1][j] + 1, f[i][j - 1] + 1);
            if (a[i] == b[j]) f[i][j] = min(f[i][j], f[i - 1][j - 1]);
            else f[i][j] = min(f[i][j], f[i - 1][j - 1] + 1);
        }
        
    cout << f[n][m] << endl;  //  结果就是让两个字符长相等f[n][m]
    
    return 0;
}

三,编辑距离

题目:

思路:

没什么思路,就跟上一个题一样的,不过只是判断了一下是否在限制内,直接上代码吧

代码:

#include <iostream>
#include <algorithm>
#include <string.h>

using namespace std;

const int N = 15, M = 1010;

int n, m;  // n 是字符串的数量 m 是询问次数
int f[N][N];  
char str[M][N];  //  存储输入的字符串数组


//  计算两个数组的编辑距离  跟上个是一样的
int edit_distance(char a[], char b[])
{
    int la = strlen(a + 1), lb = strlen(b + 1);

    for (int i = 0; i <= lb; i ++ ) f[0][i] = i;
    for (int i = 0; i <= la; i ++ ) f[i][0] = i;

    for (int i = 1; i <= la; i ++ )
        for (int j = 1; j <= lb; j ++ )
        {
            f[i][j] = min(f[i - 1][j] + 1, f[i][j - 1] + 1);
            f[i][j] = min(f[i][j], f[i - 1][j - 1] + (a[i] != b[j]));
        }

    return f[la][lb];
    
}

int main()
{
    cin >> n >> m;
    for (int i = 0; i < n; i ++ ) cin >> str[i] + 1;

    while (m -- )
    {
        char s[N];  //  询问的字符串
        int limit;  //  限制
        cin >> s + 1 >> limit;

        int res = 0;
        for (int i = 0; i < n; i ++ )
            if (edit_distance(str[i], s) <= limit)
                res ++ ;

        cout << res << endl;
    }

    return 0;
}

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

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

相关文章

ST7789读取ID错误新思路(以STC32G为例)

1.前言 前两天刚把ST7789写入搞定&#xff0c;这两天想折腾一下读取。最开始是读ID&#xff0c;先是用厂家送的程序&#xff0c;程序里面用的是模拟I8080协议&#xff0c;一切正常。后来我用STC32G的内置LCM模块&#xff0c;发现读取不出来。更神奇的是ID读不出来&#xff0c;…

【AIGC】AI如何匹配RAG知识库: Embedding实践,语义搜索

引言 RAG作为减少模型幻觉和让模型分析、回答私域相关知识最简单高效的方式&#xff0c;我们除了使用之外可以尝试了解其是如何实现的。在实现RAG的过程中Embedding是非常重要的手段。本文将带你简单地了解AI工具都是如何通过Embedding去完成语义分析匹配的。 Embedding技术简…

HTB:Headless[WriteUP]

目录 连接至HTB服务器并启动靶机 1.Which is the highest open TCP port on the target machine? 2.What is the title of the page that comes up if the site detects an attack in the contact support form? 使用浏览器访问靶机5000端口 3.What is the name of the …

海量数据在有限资源上处理的方法

1. 使用哈希 适用场景&#xff1a;需要处理的数据中&#xff0c;相同的数据可以分配到同样的机器/文件进行处理。 技巧总结&#xff1a;相同的数会哈希到同一个位置上 这类题目一般面试官给的描述都不是很清晰&#xff0c;需要自己去问条件、然后给出方案。 回答思路是&#…

hdfs的客户端(big data tools插件)

1.下载hadoop的压缩包在Windows,后解压 2.下载hadoop.dll文件和winutil.exe文件(网上自行查找) 下载完把这两个文件放入hadoop的bin目录 3.设置环境变量: $HADOOP_HOME指向hadoop的文件夹 4.在jetbrains公司的软件里下载big data tools插件:(在此展示的idea的) 下载完重启ide…

AI金融攻防赛:YOLO模型的数据增强与性能优化(DataWhale组队学习)

引言 大家好&#xff0c;我是GISer Liu&#x1f601;&#xff0c;一名热爱AI技术的GIS开发者。本系列文章是我跟随DataWhale 2024年10月学习赛的AI金融攻防赛学习总结文档。在前一篇文章中&#xff0c;我们详细介绍了如何在金融场景凭证篡改检测中应用YOLO算法。本文将在此基础…

深入了解Spring重试组件spring-retry

在我们的项目中&#xff0c;为了提高程序的健壮性&#xff0c;很多时候都需要有重试机制进行兜底&#xff0c;最多就场景就比如调用远程的服务&#xff0c;调用中间件服务等&#xff0c;因为网络是不稳定的&#xff0c;所以在进行远程调用的时候偶尔会产生超时的异常&#xff0…

渗透测试实战—教育攻防演练中突破网络隔离

免责声明&#xff1a;文章来源于真实渗透测试&#xff0c;已获得授权&#xff0c;且关键信息已经打码处理&#xff0c;请勿利用文章内的相关技术从事非法测试&#xff0c;由于传播、利用此文所提供的信息或者工具而造成的任何直接或者间接的后果及损失&#xff0c;均由使用者本…

3.matplotlib基础及用法(全)

一.基础绘图 折线图plot散点图scatter柱状图bar饼图pie 二.图表设置 设置标题设置线条设置坐标轴添加图例添加注释设置画布大小与分辨率 三.高级功能 绘制子图保存图形 一.基础绘图 1.折线图plot import matplotlib.pyplot as plt x [1, 2, 3, 4, 5] y [2, 3, 5, 7, 11] pl…

如何选择合适的电感器来匹配感性负载?

在匹配感性负载时&#xff0c;选择合适的电感器是至关重要的。电感器的主要作用是抑制电流变化&#xff0c;从而维持电路的稳定性。为了确保电路的稳定运行&#xff0c;需要考虑以下因素&#xff1a; 1. 电流和电压&#xff1a;首先&#xff0c;需要确定电感器的额定电流和额定…

GJS-WCP

不懂的就问&#xff0c;但我也是二把手......哭死 web GJS-ezssti 很常规的ssti模板注入&#xff0c;只过滤了"/","flag"。 过滤了/,flag 可以利用bash的特性绕过&#xff0c;如字符串截取&#xff0c;环境变量等等。payload1: {{url_for.__globals__[…

【uniapp】微信小程序使用echarts图表记录

1、插件引入 在Dcloud插件市场下载echarts插件&#xff1a;插件地址 或去相关代码库下载js&#xff1a;gitee地址 将static文件夹下中的echarts.min.js和ecStat.min.js复制到自己项目的static文件夹内或到echarts官方定制自己需要的图表类型下载js文件并放入相关目录。echart…

让你的 IDEA 使用更流畅 | IDEA内存修改

随着idea使用越来越频繁&#xff0c;笔者最近发现使用过程中有时候会出现卡顿现象&#xff0c;例如&#xff0c;启动软件变慢&#xff0c;打开项目的速度变慢等&#xff1a; 因此如果各位朋友觉得最近也遇到了同样的困惑&#xff0c;不妨跟着笔者一起来设置IDEA的内存大小吧~ …

【C#】在 WinForms 中使用 MVVM(Model-View-ViewModel) 设计模式

结合当前的 DevExpress 项目&#xff0c;在 WinForms 中使用 MVVM&#xff08;Model-View-ViewModel&#xff09; 设计模式。这个例子将通过数据绑定、命令绑定来展示 MVVM 模式的运用。 1. 项目结构 假设我们要实现一个简单的应用程序&#xff0c;它有一个文本框和一个按钮&…

【C++指南】类和对象(四):类的默认成员函数——全面剖析 : 拷贝构造函数

引言 拷贝构造函数是C中一个重要的特性&#xff0c;它允许一个对象通过另一个已创建好的同类型对象来初始化。 了解拷贝构造函数的概念、作用、特点、规则、默认行为以及如何自定义实现&#xff0c;对于编写健壮和高效的C程序至关重要。 C类和对象系列文章&#xff0c;可点击下…

【计网】理解TCP全连接队列与tcpdump抓包

希望是火&#xff0c;失望是烟&#xff0c; 生活就是一边点火&#xff0c;一边冒烟。 理解TCP全连接队列与tcpdump抓包 1 TCP 全连接队列1.1 重谈listen函数1.2 初步理解全连接队列1.3 深入理解全连接队列 2 tcpdump抓包 1 TCP 全连接队列 1.1 重谈listen函数 这里我们使用…

【JAVA】第三张_Eclipse下载、安装、汉化

简介 Eclipse是一种流行的集成开发环境&#xff08;IDE&#xff09;&#xff0c;可用于开发各种编程语言&#xff0c;包括Java、C、Python等。它最初由IBM公司开发&#xff0c;后来被Eclipse Foundation接手并成为一个开源项目。 Eclipse提供了一个功能强大的开发平台&#x…

IDEA如何查看所有的断点(Breakpoints)并关闭

前言 我们在使用IDEA开发Java应用时&#xff0c;基本上都需要进行打断点的操作&#xff0c;这方便我们排查BUG&#xff0c;也方便我们查看设计的是否正确。 不过有时候&#xff0c;我们不希望进入断点&#xff0c;这时候除了点击断点关闭外&#xff0c;有没有更快速的方便关闭…

深度解析机器学习的四大核心功能:分类、回归、聚类与降维

深度解析机器学习的四大核心功能&#xff1a;分类、回归、聚类与降维 前言分类&#xff08;Classification&#xff09;&#xff1a;预测离散标签的艺术关键算法与代码示例逻辑回归支持向量机&#xff08;SVM&#xff09; 回归&#xff08;Regression&#xff09;&#xff1a;预…

HarmonyOS Next应用开发——图像PixelMap变换

【高心星出品】 图像变换 图片处理指对PixelMap进行相关的操作&#xff0c;如获取图片信息、裁剪、缩放、偏移、旋转、翻转、设置透明度、读写像素数据等。图片处理主要包括图像变换、位图操作&#xff0c;本文介绍图像变换。 图形裁剪 // 裁剪图片 x&#xff0c;y为裁剪的起…