一,    最长递增子序列问题的描述

设L=<a1,a2,…,an>是n个不同的实数的序列,L的递增子序列是这样一个子序列Lin=<aK1,ak2,…,akm>,其中k1<k2<…<km且aK1<ak2<…<akm。求最大的m值。

比如int* inp = {9,4,3,2,5,4,3,2}的最长递减子序列为{9,5,4,3,2};

二,解决:

1.用一个临时数组tmp保存这样一种状态:tmp[i]表示以i为终点的递增序列的长度;

比如inp = {3,2,5}那么tmp = {1, 1, 2},其中tmp[2]=2表示包含i=2位(inp[2]=5)的LIS的个数,即序列{3,5},个数为2;

2.假设已经知道了tmp[0]到tmp[n-1],那我们如何通过tmp[0]到tmp[n-1]的状态求得tmp[n]的状态?

比如inp = {3,2,5},已经求得tmp[0]=1,tmp[1]=1,怎么求tmp[2]?

如果i<2那,i就有可能在2为终点的LIS序列上,那以2为终点的递增序列的长度就至少是i的最长序列+1,那么就必须满足以下两个条件:

inp[i]<inp[n]          tmp[i]+1>tmp[n]

比如i=0时,inp[0]=3<inp[n]=5且tmp[0]+1=2>tmp[2]=1(tmp[i]初值都为1);则赋值tmp[2] = tmp[0]+1=2;

继续比较i=1,此时inp[1]=2<inp[n]=5且tmp[1]+1=2不大于tmp[2]=2;

一直循环到n-1位为止!最后得到tmp = {1, 1, 2};

其中tmp的最大元素即为LIS的最大长度!

3.我们如何输出LIS的所有的值呢?

其实我们只需要知道LIS中,每个元素的前面一位元素的位置即可:

比如tmp = {1, 1, 2}的最大值是2,该LIS最后一位元素出现在i=2位,如果我们保存inp[2]=5在LIS中前面的那个元素,以此类推,我们就能找到LIS中所有元素;

比如{3,2,5}的LIS是{3,5}或{2,5},我们用另一个临时数组存储它前一位元素下标int arr = {-1,-1,0},表示以inp[2]=5结尾的LIS,其前一位元素的小标是0,即inp[0]=3,这样就找到了{3,2,5}的LIS是{3,5};

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <assert.h>
//求最长递增子序列;
//ret[i]存放包含第i位的LIS的元素个数;
//path用于保存最长递增子序列路径;path[i]存放包含第i位的LIS的前一位元素的下标;
int LIS(int* inp,int len,int* ret,int* path){assert(inp);if(len <= 0) return;int i = 0,max = 0,maxpoint = 0;for(;i<len;i++){ret[i] = 1;path[i] = -1;//初始值都-1,为了以后输出方便,初值0时和path[0]混淆;int j = 0;for(;j<i;j++){if(inp[i] > inp[j] && ret[j]+1 > ret[i]){ret[i] = ret[j] + 1;path[i] = j;}}printf("ret[i] ==%d\n",ret[i]);if(ret[i] > max){max = ret[i];maxpoint = i;//ret中最大的那个元素的下标;
     } }return maxpoint;
}//输出数组
void printinp(int* inp,int len){int i = 0;for(;i<len;i++){printf("inp = %d\n",inp[i]);}
}//输出LIS;LIS中-1表示:包含该位元素的LIS,其前面没有元素;
void printpath(int* inp,int* path,int key){for(;key>=0;){printf("inp[%d]=%d\n",key ,inp[key]);if(key == 0) break;//path[0]处会死循环,必须跳出key = path[key];}
}int main(){int inp[] = {2,9,4,6,8,7,1,3,5};int len = sizeof(inp)/sizeof(int);int ret[len];int path[len];int maxpoint = LIS(inp,len,ret,path);printpath(inp, path, maxpoint);
}

输出结果:

ret[i] ==1
ret[i] ==2
ret[i] ==2
ret[i] ==3
ret[i] ==4
ret[i] ==4
ret[i] ==1
ret[i] ==2
ret[i] ==3
inp[4]=8
inp[3]=6
inp[2]=4
inp[0]=2

LIS结果是8 6 4 2,输出正确!

转载于:https://www.cnblogs.com/McQueen1987/p/4041707.html

LIS 最长递增子序列问题相关推荐

  1. 算法设计 - LCS 最长公共子序列最长公共子串 LIS 最长递增子序列

    出处 http://segmentfault.com/blog/exploring/ 本章讲解: 1. LCS(最长公共子序列)O(n^2)的时间复杂度,O(n^2)的空间复杂度: 2. 与之类似但不 ...

  2. LIS 最长递增子序列

    前言 LIS 即 longest increasing string,最长递增子序列,可以是不连续的.例如 2 3 5 2 3 4 5 的最长递增子序列为{2,3,4,5},长度为4. 两种方法可以求 ...

  3. 数组字符串那些经典算法:最大子序列和,最长递增子序列,最长公共子串,最长公共子序列,字符串编辑距离,最长不重复子串,最长回文子串 (转)...

    作者:寒小阳 时间:2013年9月. 出处:http://blog.csdn.net/han_xiaoyang/article/details/11969497. 声明:版权所有,转载请注明出处,谢谢 ...

  4. [51Nod 1218] 最长递增子序列 V2 (LIS)

    传送门 Description 数组A包含N个整数.设S为A的子序列且S中的元素是递增的,则S为A的递增子序列.如果S的长度是所有递增子序列中最长的,则称S为A的最长递增子序列(LIS).A的LIS可 ...

  5. 51Nod-1134 最长递增子序列【LIS】

    1134 最长递增子序列 基准时间限制:1 秒 空间限制:131072 KB 分值: 0 难度:基础题 给出长度为N的数组,找出这个数组的最长递增子序列.(递增子序列是指,子序列的元素是递增的) 例如 ...

  6. 动态规划 —— 最长递增子序列(LIS)

    LIS:Longest Increasing Subseq,最长递增子序列,是不要求该子序列在原始序列中间连续存放的. 为了降低对这一问题的理解难度,既然最长递增子序列不要求子序列位置连续,我们不妨先 ...

  7. 耐心排序之最长递增子序列(LIS)

    目录 一.问题引入 1.最长递增子序列(LIS) 2.问题分析 3.代码实现 4.问题思考 二.耐心排序 1.基本介绍 2.操作步骤 3.代码实现 三.俄罗斯套娃信封问题 1.题目描述 2.问题分析 ...

  8. python最大连续递增子列_最长递增子序列(LIS)解法详述

    求数组中最长递增子序列(Longest Increasing Subsequence, LIS) LIS问题是算法中的经典题目,传统的解法是使用动态规划,时间复杂度是O(n^2):改进的方法时间复杂度 ...

  9. CCNU ACM 2016夏季集训·最长递增子序列(LIS)

    这几天dp写得难受-- 在讨论这个问题之前,首先明确:"子序列"是指从原序列中挑选出若干元素,按照原序列中的顺序组成新的序列(区别于"子串",即从原序列中挑选连 ...

最新文章

  1. 工信部 学习类app_工信部整治APP侵权行为,私自收集个人信息等8类问题被点名...
  2. 学习web前端开发要注意什么
  3. 简单读!tomcat源码(一)启动与监听
  4. 验证码实现(随机背景色及字体颜色,带扰乱线条)
  5. python基础教程:名称空间与作用域
  6. csdn的自动化评论
  7. 深度学习(二十三)——Fast Image Processing, SVDF, LCNN, LSTM进阶
  8. 提升开发效率的十个工具
  9. 哥廷根,世界数学家的摇篮和圣地
  10. docker部署web项目_IntelliJ IDEA 部署 Web 项目
  11. python知识总结os**
  12. 开元弧焊机器人编程_【数据】2019年中国焊接机器人市场发展现状与趋势分析...
  13. HFSS阵列天线仿真
  14. CameraLink简介
  15. 王道中数据结构的排序算法
  16. Python文件操作错误:OSError: [Errno 22] Invalid argument(关于Windows下文件名中的敏感字符)
  17. 测试之smart原则
  18. 机器学习 Cohen s Kappa,Quadratic Weighted Kappa 详解
  19. 2021年秋招面试真题以及面试技巧分享
  20. linux C-kermit 安装使用

热门文章

  1. 50秒开门,3分钟开走,特斯拉Model S就这样不翼而飞
  2. 天天写代码,觉得自己特别苦逼?嗯,还有20年AI就来解放你
  3. Spark createDirectStream 维护 Kafka offset(Scala)
  4. 日调度5万亿次 腾讯云微服务架构体系TSF深度解读
  5. 未来已来——工作空间 WorkSpace 和物联网 IoT (1)
  6. Commons Configuration之一简介
  7. React学习笔记—属性转移
  8. IIS服务器应用程序不可用的解决办法
  9. 《奠基计算机网络》所需软件 下载地址
  10. 51CTO网站博客改版意见寻求