每日练题之动态规划(子序列问题讲解 1.最长递增子序列的个数 2.最长数对链)

 前言:

在算法的广袤天地中,动态规划犹如一颗璀璨的明珠,散发着独特的智慧光芒。而子序列问题,则是动态规划领域中极具代表性且应用广泛的重要板块。

每日练题,是我们在编程与算法学习之路上的坚实脚印。在深入探索动态规划的旅程里,子序列问题犹如一座充满挑战与奥秘的山峰等待我们攀登。通过对其细致入微的讲解与练习,我们将逐步揭开动态规划处理子序列问题的神秘面纱。无论是最长递增子序列那优雅的递推思路,还是公共子序列蕴含的巧妙状态转移,都将在我们的每日钻研中清晰呈现。

在这里,你将见证如何运用动态规划的思想,将看似复杂多变的子序列问题拆解为一个个可解的子任务,以精准的状态定义、合理的状态转移方程构建起高效的解题框架。每一道精心挑选的练习题,都是我们磨砺思维、提升算法能力的宝贵契机。让我们在每日练题中,沉浸式感受动态规划与子序列问题碰撞出的智慧火花,开启一场充实且富有成就感的算法学习之旅,为成为更卓越的编程者和算法高手奠定坚实的基础。

今日讲题:

1.最长递增子序列的个数

1.题目解析:

给定一个未排序的整数数组 nums , 返回最长递增子序列的个数 。

注意 这个数列必须是 严格 递增的。

2.讲解算法原理

示例1
13547

我们从头开始选,如果我们后一项大于前一项时,我们就开始统计这一串中的最长递增子序列。

例如我们拿到的第一串:1 - 3 - 5 - 7 我们记下这一串的长度 len = 4 ,当我们再次开始寻找时: 1 - 3 - 4 - 7 这时候我们就要判断和我们之前记得那组数据长度了:

1.如果(新子串的长度)Rmax == len 时 我们就让retcount++;

2.  如果(新子串的长度)Rmax <= len 时 可以忽略不计;

3. 如果(新子串的长度)Rmax >= len 时, 我们就要开始重新统计数量,并把之前统计的数量重新修改为初始值(1)即可 ;

1.状态表示:

由上所述:

我们只定义 dp[i] 表示:以i位置元素为结尾的所有的子序列中,最长递增子序列的个数 是不行的,

所以我们要定义:
len[i] 表示:以ì位置元素为结尾的所有的子序列中,最长递增子序列的"“长度"

count[i] 表示:以ì位置元素为结尾的所有的子序列中,最长递增子序列的“个数”

这两个状态表示来定义

2.状态转移表示:

1.当数组长度为 1 时 我们的 len[i] = 1

2.当数组长度不为1时 :

如果我们后一项大于前一项时,我们就开始统计这一串中的最长递增子序列。

但是在实例2中我们可以看到如果 前后两个值相同时我们也要统计:

1.(后一项) len[j] + 1 ==(前一项)len[j] 时 count[i] += count[j];

2.当(后一项) len[j] + 1 >(前一项)len[j] 时, len[i] = len[j] + 1;  count[i] = count[j];

3.初始化:

因为只有一个元素时,长度为一,所以我们把初始值都设为一,即可省略为1的这种情况,


4.填表顺序:

从左往右,两个表一起填

5.返回值:

返回统计的数字recount

3.编写代码

2. 最长数对链

1.题目解析

给你一个由 n 个数对组成的数对数组 pairs ,其中 pairs[i] = [lefti, righti] 且 lefti < righti

现在,我们定义一种 跟随 关系,当且仅当 b < c 时,数对 p2 = [c, d] 才可以跟在 p1 = [a, b] 后面。我们用这种形式来构造 数对链

找出并返回能够形成的 最长数对链的长度

你不需要用到所有的数对,你可以以任何顺序选择其中的一些数对来构造。

2.讲解算法原理

1.状态表示:

预处理:按照第一个元素排序即可

Arrays.sort(pairs,(a,b)-> a[0] - b[0]);

dp[i] 表示:以i位置元素为结尾的所有的子序列中,最长数对链的长度的个数

2.状态转移表示:

当我们所有元素按照第一个元素排序后,我们只需要判断后一项的第一个数字大于前一项的第二个数字即可:

if(pairs[i][0] > pairs[j][1]) 如果满足了,我们就加1,不满足就返回当前符合的元素个数:

dp[i] =Math.max( dp[j]+1,dp[i]);

3.初始化

表里面的所有值初始化为 1

4.填表顺序

从左往右

5.返回值

dp 表里面的最大值

3.编写代码

上期链接:

每日练题之动态规划(子序列问题讲解 1.最长递增子序列 2.摆动序列)-CSDN博客

下期预告:

感兴趣的小伙伴们可以先看看题呦,一起加油!!! 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

study hard_day

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值