【动态规划】最长上升子序列(单调队列、贪心优化)

Halo,这里是Ppeua。平时主要更新C语言,C++,数据结构算法......感兴趣就关注我吧!你定不会失望。

 

个人主页:主页链接

算法专栏:专栏链接

     我会一直往里填充内容哒!

LeetCode专栏:专栏链接 

    目前在刷初级算法的LeetBook 。若每日一题当中有力所能及的题目,也会当天做完发出

代码仓库:Gitee链接

点击关注=收获更多优质内容

【动态规划】最长上升子序列(单调队列、贪心优化)_第1张图片

目录

题目:最长上升子序列

题解:

代码实现:

完结撒花:


本篇是对最长上升子序列基础做法的一种优化,没有看过基础做法的uu们可以看看这篇:最长上升子序列 

题目:最长上升子序列

【动态规划】最长上升子序列(单调队列、贪心优化)_第2张图片

题解:

优化的做法与之前相比,适用范围更广,当数据范围大的时候,基础做法会TLE。

但优化做法Dp的思想却少了,更像是一种贪心,由于本题是从DP衍生出来的,所以仍然将其归为DP。

废话不多说。

朴素做法为,找到前一个小于当前值,将其最长上升子序列加一,就为当前值得最长上升子序列。

但观察每一个被插入得值,例如有以下五个数字

3和1都为上升序列为1的数组,但能插入到1上的一定能插到三的上面,反之却不一定。所以我们可以想象出,只要保存上升序列长度中最小的那个值最为末端就可以了。

例如这里的3和1都为长度为1的上升序列,但我们只要保存1.

【动态规划】最长上升子序列(单调队列、贪心优化)_第3张图片

 

之后再将2插入到1上,此时更新上升序列长度为2的最后一个值为2.

4又可以插入到2后,所以更新长度为3的最后一个值为4。

【动态规划】最长上升子序列(单调队列、贪心优化)_第4张图片

 

最后如图所示

【动态规划】最长上升子序列(单调队列、贪心优化)_第5张图片

所以我们很容易就能归纳出上面的过程,找到最大小于待插入数的序列,在下一个位置更新其序列长度与队尾的值。

分析下代码实现,len为当前最长的子序列,利用二分查找寻找,最大的小于当前值x的位置,之后将下一个最长子序列的末位更新为x。循环往复即可

代码实现:

#include
#include
using namespace std;
const int N=100010;
int n;
int a[N];
int q[N];

int main()
{
    cin>>n;
    for(int i=0;i>a[i];
    }
    int len=0;
    q[0]=-2e9;
    for(int i=0;i>1;
            if(q[mid]

完结撒花:

本篇博客的内容【动态规划:最长上升子序列(单调队列、贪心优化)】已经结束。

若对你有些许帮助,可以点赞、关注、评论支持下博主,你的支持将是我前进路上最大的动力。

若以上内容有任何问题,欢迎在评论区指出。若对以上内容有任何不解,都可私信评论询问。

诸君,山顶见!

你可能感兴趣的:(动态规划,算法,leetcode,贪心算法,蓝桥杯)