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

设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 <= ) return;
int i = ,max = ,maxpoint = ;
for(;i<len;i++){
ret[i] = ;
path[i] = -;//初始值都-1,为了以后输出方便,初值0时和path[0]混淆;
int j = ;
for(;j<i;j++){
if(inp[i] > inp[j] && ret[j]+ > ret[i]){
ret[i] = ret[j] + ;
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 = ;
for(;i<len;i++){
printf("inp = %d\n",inp[i]);
}
} //输出LIS;LIS中-1表示:包含该位元素的LIS,其前面没有元素;
void printpath(int* inp,int* path,int key){
for(;key>=;){
printf("inp[%d]=%d\n",key ,inp[key]);
if(key == ) break;//path[0]处会死循环,必须跳出
key = path[key];
}
} int main(){
int inp[] = {,,,,,,,,};
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] ==
ret[i] ==
ret[i] ==
ret[i] ==
ret[i] ==
ret[i] ==
ret[i] ==
ret[i] ==
ret[i] ==
inp[]=
inp[]=
inp[]=
inp[]=

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

LIS 最长递增子序列问题的更多相关文章

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

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

  2. LIS 最长递增子序列

    一.最长公共子序列 经典的动态规划问题,大概的陈述如下: 给定两个序列a1,a2,a3,a4,a5,a6......和b1,b2,b3,b4,b5,b6.......,要求这样的序列使得c同时是这两个 ...

  3. 300. Longest Increasing Subsequence(LIS最长递增子序列 动态规划)

    Given an unsorted array of integers, find the length of longest increasing subsequence. For example, ...

  4. 最长递增子序列(LIS)

    最长递增子序列(Longest Increasing Subsequence) ,我们简记为 LIS. 题:求一个一维数组arr[i]中的最长递增子序列的长度,如在序列1,-1,2,-3,4,-5,6 ...

  5. 最长公共子序列(LCS)和最长递增子序列(LIS)的求解

    一.最长公共子序列 经典的动态规划问题,大概的陈述如下: 给定两个序列a1,a2,a3,a4,a5,a6......和b1,b2,b3,b4,b5,b6.......,要求这样的序列使得c同时是这两个 ...

  6. 2.16 最长递增子序列 LIS

    [本文链接] http://www.cnblogs.com/hellogiser/p/dp-of-LIS.html [分析] 思路一:设序列为A,对序列进行排序后得到B,那么A的最长递增子序列LIS就 ...

  7. 算法面试题 之 最长递增子序列 LIS

    找出最长递增序列 O(NlogN)(不一定连续!) 参考 http://www.felix021.com/blog/read.php?1587%E5%8F%AF%E6%98%AF%E8%BF%9E%E ...

  8. 最长递增子序列(lis)最长公共子序列(lcs) 最长公共上升子序列(lics)

    lis: 复杂度nlgn #include<iostream> #include<cstdio> using namespace std; ],lis[],res=; int ...

  9. 最长递增子序列(LIS)(转)

    最长递增子序列(LIS)   本博文转自作者:Yx.Ac   文章来源:勇幸|Thinking (http://www.ahathinking.com)   --- 最长递增子序列又叫做最长上升子序列 ...

随机推荐

  1. elasticsearch的rest搜索--- 总述

    目录: 一.针对这次装B 的解释 二.下载,安装插件elasticsearch-1.7.0   三.索引的mapping 四. 查询 五.对于相关度的大牛的文档 一.针对这次装B 的解释  因为现在又 ...

  2. 关于微软公有云Azure会计标准

    前几年.中国的云计算项目往往搞成了房地产项目.大搞形"象project",没有实质性的内容.云计算老总成了房地产大老板,国内业界是在胡闹! 现今,世纪互联与微软(中国)联手搞公有云 ...

  3. ExtJS得知--------Ext.Element学习的查询方法(示例)

    详细实例:(实验结果可复制代码后进行演示) Ext.onReady(function(){ Ext.create('Ext.panel.Panel',{//创建一个面板 title:'我的面板' , ...

  4. PsExec.exe执行远程程序

    PsExec.exe \\192.168.1.1 -u username -p password -i -d -s c:\Windows\system32\NETSTAT.exe -a

  5. JS开发调试

    开发调试工具   页面制作之开发调试工具(1) 开发工具介绍 开发工具一般分为两种类型:文本编辑器和集成开发环境(IDE) 常用的文本编辑器:Sublime Text.Notepad++.EditPl ...

  6. Swift # Apple Pay集成

    苹果正式开放了Apple Pay支付系统.Apple Pay是一个基于NFC的支付系统,不久将被数以万计的线下零售商店予以支持.即便这项科技并不是彻底的突破性进展,但它足以推动许多公司和零售商来支持这 ...

  7. Java初认识--环境搭建及基本数据类型

    一.JAVA语言的环境搭建 1.JRE(Java Runtime Environment):Java运行环境. 它包括Java虚拟机和Java程序所需的核心类库等. 2.JDK(Java Develo ...

  8. 将程序添加到右键菜单和图标(以记事本、UltraEdit为例)

    原文:将程序添加到右键菜单(以记事本.UltraEdit为例) 如何将程序加入右键菜单,这里分别以记事本.UltraEdit为例! 以记事本程序为例: 1. 在运行中输入regedit,打开注册表,找 ...

  9. Errors occurred during the build. Errors running builder &#39;JavaScript Validator&#39; on

    eclipse又一次编译时候就会报错Errors occurred during the build. Errors running builder 'JavaScript Validator' on ...

  10. sql级联删除

    原文:sql级联删除 功能:在删除主表时,自动删除副表(外键约束)相应内容 删除包含主键值的行的操作,该值由其它表的现有行中的外键列引用.在级联删除中,还删除其外键值引用删除的主键值的所有行. 如: ...