动态规划算法(子序列专题1)

news2024/11/28 12:30:20

动态规划算法专辑之子序列问题(1)

本专栏将从状态定义、状态转移方程、初始化、填表顺序、返回值这五大细节来详细讲述动态规划的算法的解题思路及代码实现

一、什么是子序列

子数列,又称子序列,在数学中,某个序列的子序列是从最初序列通过去除某些元素但不破坏余下元素的相对位置(在前或在后)而形成的新序列。

例如,[3,6,2,7] 是数组 [0,3,1,6,2,2,7] 的子序列。

下面我们将通过几道经典例题来进行讲述

二、最长递增子序列

image-20230614000242723

1.题目解析

严格递增:第i个元素一定比i-1大

非严格递增:第i个元素可能比i-1大,也可能相等

要从数组中的n个子序列中,找出所有递增的子序列,并在里面找到最长的,最后返回它的长度

2.状态定义

根据经验+题目要求,我们可以得到如下定义:

dp[i]表示,以下标i元素为结尾的递增子序列的最长长度

3.状态转移方程

image-20230614161226883

通过上图,我们可以发现,dp[i]有两种状态,一种是它自己就是递增子序列,一种是和前面的任意个元素组成递增子序列,对于第二种情况,我们首先要保证前面0到i-1的元素是小于nums[i]的,同时又要dp[i]是最长的长度,所以需要在0到i-1中找到最长子序列,综上,状态转移可以得到下图:

image-20230614162408634

根据上图,我们可以得到如下的状态转移方程:

image-20230614162630611

4.初始化

初始化也是根据题目要求+经验来进行的,并不是墨守成规的初始化为0

根据上述的状态转移方程和状态定义,我们可以将dp表里的值初始化为1,这样就对于长度为1的递增子序列,我们就不用再进行判断和计算了,使得状态只有一个了,大大简化了编码的实现

5.填表顺序

填表的顺序主要看的是状态转移方程,在方程中,dp[i]受dp[j]影响,而j又是小于i的,所以应该从左往右进行填表

6.返回值

本地不能简单的返回dp[n-1],因为他不一定是最长的递增子序列,他只是以n-1为结尾的最长递增子序列的长度,所以我们需要遍历dp表,返回里面的最大值

7.代码实现

class Solution {
public:
    int lengthOfLIS(vector<int>& nums) {
        int n = nums.size();
        vector<int> dp(n,1);
        int res = 1;
        for(int i=1;i<n;i++)
        {
            for(int j=0;j<i;j++)
            {
                if(nums[j] < nums[i])
                {
                    dp[i] = max(dp[i],dp[j]+1);
                }
            }
            //填表的同时更新最大值,减少了一次for循环的遍历
            res = max(dp[i],res);
        }

        return res;
    }
};

三、最长斐波那契数列

1.题目解析

image-20230614164245691

在n个子序列中,找到所有符合斐波那契数列形式的子序列,并返回最长的长度

image-20230614164946801

2.状态定义

根据题目+经验,dp[i]表示:以i为结尾的斐波那契式的子序列的最长的长度

状态分析:

image-20230614165853650

新的状态定义:

dp[i] [j]表示:以i及j位置为结尾的斐波那契式子序列的最长的长度(i<j)

3.状态转移方程

image-20230614170813591

优化:由于数组中的元素是严格递增的,所以a的值是唯一确定的,所以a的下标也是唯一确定的,因此可以建立元素和元素下标的映射,并存入哈希表中,这样对于a的查找就大大简化了

image-20230614171511712

4.初始化

根据状态定义,表里的所有值应该初始化为2,对于dp表最少有两个元素i和j

5.填表顺序

从状态转方程中看出,k<i<j,,所以应该从左到右从上到下进行填表

6.返回值

和最长递增子序列一样,应该返回的是dp表里的最大值,注意,斐波那契式的子序列的最小长度应该为3,当结果小于3时,应该返回0

7.代码实现

class Solution {
public:
    int lenLongestFibSubseq(vector<int>& arr) {
        int n = arr.size();
        unordered_map<int,int> hash;
        for(int i=0;i<n;i++)
            hash[arr[i]] = i;
        vector<vector<int>> dp(n,vector<int>(n,2));
        int res = 2;
        for(int j = 2;j<n;j++)
        {
            for(int i=0;i<j;i++)
            {
                int a = arr[j] - arr[i];
                if(hash.count(a) && a < arr[i])
                {
                    int k = hash[a];
                    dp[i][j] = dp[k][i]+1;
                }
                res = max(dp[i][j],res);
            }
        }

        return res < 3 ? 0 : res;
    }
};

四、总结

本文所涉及的知识点:一维dp和二维dp,初始化的细节,状态定义(要大胆进行状态定义,错了,再改就行,当状态转移方程定义不出来的时候),返回值的细节,如何判断填表顺序

相信通过上述的两个例题,你对动态规划及子序列问题有了一定的感觉了,但对于上述问题,本文给的不一定是最优解,只是基于动态规划算法给出的解法,对于子序列问题,分析状态转移大差不差,你也可以尝试去做一些其他题练练手

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

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

相关文章

工时表:如何跟踪团队进度?

工时表可以记录考勤&#xff0c;但你知道它还能帮助你管理项目和监控团队绩效吗&#xff1f;在本文中&#xff0c;了解如何将在线时间跟踪与你的日常工作流程相结合&#xff0c;以调整你的团队并提高灵活性。 在线时间追踪与手动 传统上&#xff0c;工时表在每天或每周开始时…

基于Java企业办公自动化系统设计实现(源码+lw+部署文档+讲解等)

博主介绍&#xff1a; ✌全网粉丝30W,csdn特邀作者、博客专家、CSDN新星计划导师、java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战 ✌ &#x1f345; 文末获取源码联系 &#x1f345; &#x1f447;&#x1f3fb; 精…

【干货分享】安卓加固原理分享

之前写过几篇ios加固的文章&#xff0c;感兴趣可以看一下。最近攒了一下收集的一些资料&#xff0c;打算简单写一下安卓加固相关的内容。今天先简单写一篇安卓加固原理的分享。 App会面临的风险 我们首先了解一下为什么需要加固&#xff0c;尤其是安卓APP&#xff0c;下面是A…

【网络攻击】面对网络攻击,我们该如何防范?

网络攻击手段的种类繁多&#xff0c;其中主要攻击手段的有钓鱼网站、恶意软件社交媒体欺诈等。在这篇文章中&#xff0c;我们将探讨这些攻击方式&#xff0c;并提供几种有效的防范方法。 一、钓鱼网站 钓鱼网站是一种欺诈行为&#xff0c;攻击者以虚假的方式获取用户的个人信息…

FPC的发展及应用,软板行业未来将持续增长

FPC系列文章目录 1.什么是FPC 2.什么是R-FPC 3&#xff0c;FPC的基材 4.FPC基材压延铜和电解铜的区别 5&#xff0c;FPC的辅材 6&#xff0c;FPC常见的四种类型 7&#xff0c;FPC的生产流程简介 8&#xff0c;R-FPC的生产流程简介 9&#xff0c;FPC的发展及应用 提示&…

【LLM GPT】大型语言模型 理解和实现

目录 1 概述1.1 发展历程1.2 预训练监督学习预训练的好处 1.3 增强式学习1.4 对训练数据的记忆1.5 更新参数1.6 AI内容检测1.7 保护隐私 1 概述 怎么学习&#xff1f;——给定输入和输出&#xff1a; 但是这样做不现实&#xff0c;因为这样输入-输出需要成对的资料&#xff0…

SpringBoot用线程池ThreadPoolTaskExecutor异步处理百万级数据

SpringBoot用线程池ThreadPoolTaskExecutor异步处理百万级数据 更多优秀文章&#xff0c;请扫码关注个人微信公众号或搜索“程序猿小杨”添加。 一、背景&#xff1a; 利用ThreadPoolTaskExecutor多线程异步批量插入&#xff0c;提高百万级数据插入效率。ThreadPoolTaskExecut…

AI+低代码:开发革命的崭新纪元!带你一文速通了解

信息技术、通信技术和计算能力的迅速发展&#xff0c;AI技术在诸多领域中掀起了一股革命浪潮&#xff0c;成为推动社会进步和发展的重要力量&#xff0c;也是许多国家和企业日益重视和投资的方向。 而全球化和技术革新的深入推进&#xff0c;传统产业对劳动力的需求逐渐减少&am…

阿里飞猪三面

&#xff08;有许多人是用青春的幸福作成功的代价的。——莫扎特&#xff09; 背景 该岗位是阿里飞猪的前端部门&#xff0c;岗位名称是node.js高级/专家开发工程师。主要负责用NodeJs作为后端技术&#xff0c;向上层Java&#xff0c;Node等业务服务&#xff0c;提供中间层基础…

操作教程:如何正确配置让EasyNVR级联至EasyNVS平台?

EasyNVS是EasyNVR的云管理平台&#xff0c;可实现内网监控上云&#xff0c;视频汇聚等功能。近期经常有用户咨询EasyNVR如何级联至EasyNVS平台进行云端统计和管理&#xff0c;在今天的文章中&#xff0c;我们来详细介绍一下。 1、配置EasyNVS 1&#xff09;运行EasyNVS之前&a…

Quarkus - 发布JSON Restful服务

目标 基于实现第一个Hello World发布一个JSON的Restful服务&#xff0c;该服务提供GET,POST,DELETE三个接口&#xff0c;分别是获取水果列表&#xff0c;添加水果&#xff0c;根据水果名字删除水果。 发布Rest服务 POM配置 添加jackson扩展的依赖 <dependency><gr…

Oralce系列十八:Oracle RAC

Oracle RAC 1. Oracle RAC介绍1.1 基本概念1.2 Oracle RAC应用场景1.3 Oracle RAC的优缺点 2. Oracle RAC架构3. Oracle RAC 的安装 1. Oracle RAC介绍 1.1 基本概念 Oracle RAC&#xff08;Oracle Real Application Server Cluster&#xff09;是一种分布式数据库解决方案&a…

涂鸦T2-U开发板快速入门

文章目录 T2-U模组概述特性 1、环境搭建2、SDK下载3、编译3.1、 命令编译3.2、 命令编译清除3.3、 Wind-IDE 编译3.4、编译完成 4、下载4.1、 GUI工具4.2、Wind IDE一键下载 5、 运行 涂鸦 T2-U 开发板 是一款专为开发者打造的智能硬件产品原型开发板。它可与其他功能电路模组或…

App的回归测试,有什么高效的测试方法?

直接抛出观点&#xff1a;高效的测试方法当然有&#xff0c;那就是采用【接口自动化】。 为了系统阐述这个问题&#xff0c;让你能有较强烈的获得感&#xff0c;本篇文章将采用下列结构进行展开&#xff1a; 1、回归测试&#xff0c;测哪些东西&#xff1f; 2、传统的回归测试…

容器认证有什么等级?考试内容是什么?

信息通信行业是进几十年新兴起的一个行业&#xff0c;对我们的生活产生了巨大的影响&#xff0c;传统的购物、出行方式发生了巨大的变化&#xff0c;而且我们的眼界更加开阔。可以了解到世界各地的风土人情&#xff0c;这一切都离不开信息通信技术的发展&#xff0c;同时市场为…

拥有Android开发经验? 走出焦虑圈,车载应用开发正好合适你!

行业前景 当前&#xff0c;车联网已成为智能交通的重要发展方向之一。车载Android应用可以为车辆提供智能化服务&#xff0c;帮助驾驶者增强车辆控制和安全&#xff0c;提供大量娱乐和信息服务&#xff0c;如导航、音乐、天气预报、电子地图等。而且&#xff0c;车联网相关政策…

为什么APP安全很重要?APP盾如何提供帮助?

为什么APP安全很重要&#xff1f; APP安全是流程、功能、控制、功能、最佳实践和工具的有效和高效组合&#xff0c;用于通过主动查找和保护各种漏洞来确保各类APP/软件的安全。 应用安全非常重要的4个主要原因 1.确保关键数据资产的安全 数据是新的石油&#xff0c;攻击者最…

抖音seo矩阵号源码开发分享(一)

抖音SEO矩阵系统源码开发&#xff0c;需要遵循一下步骤&#xff1a; 1. 确定需求和功能&#xff1a;明确系统的主要目标和需要实现的功能&#xff0c;包括关键词研究、短视频制作、外链建设、数据分析、账号设置优化等方面。 2. 设计系统架构&#xff1a;根据需求和功能确定系…

运维圣经:DDos攻击应急响应指南

目录 DDos攻击简介 DDos攻击应急响应指南 一. 问题排查 二. 临时处置 三. 研判溯源 四. 清楚加固 DDos攻击简介 分布式拒绝服务是种基于DoS的特殊形式的拒绝服务攻击&#xff0c;是一种分布、 协作的大规模攻击方式&#xff0c;主要瞄准比较大的站点&#xff0c;像商业公…

MFC没有IMEMode 想软件自动切换到英文状态以便扫码时不会变成汉字。 MFC-自定义控件Edit control。MFC禁用中文输入法

0、直接说最终解决方法&#xff1a;MFC禁用中文输入法 #include <Imm.h> // Function for Disabling IME 禁用中文输入法 void DisableIME(HWND hWnd) {HIMC m_hImc; // 全局或者成员变量//HWND hWnd pWnd->GetDlgItem(IDC_EDIT1)->m_hWnd;if (hWnd &&am…