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

设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. CSharp设计模式读书笔记(15):命令模式(学习难度:★★★☆☆,使用频率:★★★★☆)

    命令模式(Command Pattern):将一个请求封装为一个对象,从而让我们可用不同的请求对客户进行参数化:对请求排队或者记录请求日志,以及支持可撤销的操作.命令模式是一种对象行为型模式,其别名为 ...

  2. my97 日期控件

    官网:http://www.my97.net/   好多广告啊! 文档地址: http://www.mysuc.com/test/My97DatePicker/

  3. 深入理解C指针之三:指针和函数

    原文:深入理解C指针之三:指针和函数 理解函数和指针的结合使用,需要理解程序栈.大部分现代的块结构语言,比如C,都用到了程序栈来支持函数的运行.调用函数时,会创建函数的栈帧并将其推到程序栈上.函数返回 ...

  4. C/S模式开发中如何利用WebBrowser控件制作导航窗体

    原文:C/S模式开发中如何利用WebBrowser控件制作导航窗体 转自: CSDN 相信不少同学们都做过MIS系统的开发,今天这里不讨论B/S模式开发的问题.来谈谈winform开发.用过市面上常见 ...

  5. ECLIPSE实现了界面显示所有类

    按下接口名称CTRL+T实现全面实施的接口类显示 版权声明:本文博客原创文章,博客,未经同意,不得转载.

  6. ASP.NET Web Service中使用Session 及 Session丢失解决方法 续

    原文:ASP.NET Web Service中使用Session 及 Session丢失解决方法 续 1.关于Session丢失问题的说明汇总,参考这里 2.在Web Servcie中使用Sessio ...

  7. [Elasticsearch] 邻近匹配 (一) - 短语匹配以及slop參数

    本文翻译自Elasticsearch官方指南的Proximity Matching一章. 邻近匹配(Proximity Matching) 使用了TF/IDF的标准全文搜索将文档,或者至少文档中的每一 ...

  8. SQL data reader reading data performance test

    /*Author: Jiangong SUN*/ As I've manipulated a lot of data using SQL data reader in recent project. ...

  9. 安卓CTS官方文档之兼容性方案概览

    兼容性方案概览 安卓的兼容性方案让安卓手机生产商能够很容易就开发中可兼容的安卓设备(天地会珠海分舵注:可兼容什么呢?就是可以兼容标准google提供的安卓系统可以支持的功能,以防手机生产商把开源的安卓 ...

  10. Jquery.validate表单验证

    一.用前必备官方网站:http://bassistance.de/jquery-plugins/jquery-plugin-validation/API: http://jquery.bassista ...