最长单调递增子序列问题(动态规划)

Posted 三剑客J

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了最长单调递增子序列问题(动态规划)相关的知识,希望对你有一定的参考价值。

问题

给定一个长度为N的数组,找出一个最长的单调自增子序列(不一定连续,但是顺序不能乱)。例如:给定一个长度为6的数组A{5, 6, 7, 1, 2, 8},则其最长的单调递增子序列为{5,6,7,8},长度为4.


#include<stdio.h>

#include<stdlib.h>

#include<iostream>

using std::cout;


//L,输入序列

//LIS,最长递增子序列通过LIS返回

//num,序列长度

int Longest_Increament_Subsequence(int *L, int *LIS, int num)

{

int *longest = new int[num];//记录结点最长子序列长度

int *sq = new int[num];//记录该结点所在序列中以该结点为结束结点的序列的长度

int *path = new int[num];//记录该结点的上一个结点

int *endpoint = new int[num];//记录当前序列,最长子序列的终点位置

//初始化,

for (int i = 0; i < num; i++)

{

sq[i] = 1;

longest[i] = 1;

path[i] = i;

endpoint[i] = i;

}

//从第二个结点开始,依次记录包括该结点在内的之前所有结点,分别以每个结点为终点的最长递增子序列,

//即第i个结点就分为i个子问题,而最长递增子序列就是所有子问题中最长的那个。

for (int i = 1; i < num; i++)

{

for (int j = 0; j < i; j++)//更新数组sq的值,

{

if (L[i]>L[j] && sq[i] <= sq[j])

{

sq[i] = sq[j] + 1;//更新以i结点为终点的最长递增子序列的长度,选出最大的值

path[i] = j;//记录下该结点的上一结点

}

}

//判断i结点为当前序列的单调递增子序列的最后结点,该子序列是否是当前序列的最长递增子序列

if (sq[i] <= longest[i - 1])//不是,即该结点添加进来,不没有让最长子序列+1

{

longest[i] = longest[i - 1];  //最长递增子序列仍和没加该结点之前一样

endpoint[i] = endpoint[i - 1];//终点位置也和没加一样

}

else                       //是,即该结点添加进来,让最长子序列+1

{

longest[i] = sq[i];    //最长递增子序列加一

endpoint[i] = endpoint[i];//终点位置为该结点

}

}

//根据 path数组 输出最长递增子序列

for (int i = endpoint[num-1], j = longest[num - 1] - 1; j >= 0;j--)

{

LIS[j] = L[i];

i = path[i];

}

return longest[num-1];//最长递增子序列的长度返回

}

void main()

{

//举例

int L[] = { 7, 6, 8, 3, 2 }; int num = 5;

int LIS[5]; int Long;


    //调用函数

Long=Longest_Increament_Subsequence(L, LIS,  num);

    //输出最长递增子序列

for (int i = 0; i < Long; i++) 

{

cout << LIS[i] << " ";

}

cout << "\n";

}


以上是关于最长单调递增子序列问题(动态规划)的主要内容,如果未能解决你的问题,请参考以下文章

最长单调递增子序列问题(动态规划)

单调递增最长子序列(动态规划)

动态规划 - 单调递增最长子序列

nyoj 17-单调递增最长子序列(动态规划,演算法)

JAVA动态规划,最长递增子序列的代码太难理解,求大神帮我讲解一下!

动态规划求最长递增子序列的长度