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

设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. 使用 Eclipse 的 SVN 主要插件创建项目/支/标签

    原文 阅读 Mark Phippard 该博客以及<Subversion 与版本号控制>之后,我了解到 分支/标签 是 SVN 非常棒的特性之中的一个.但我在使用推荐的 "tru ...

  2. crawler_httpclient代理访问

    public String getDocumentByProxy(String url) throws ClientProtocolException, IOException { DefaultHt ...

  3. Entity Framework加载相关实体——延迟加载Lazy Loading、贪婪加载Eager Loading、显示加载Explicit Loading

    Entity Framework提供了三种加载相关实体的方法:Lazy Loading,Eager Loading和Explicit Loading.首先我们先来看一下MSDN对三种加载实体方法的定义 ...

  4. 前端学习笔记(zepto或jquery)——对li标签的相关操作(四)

    对li标签的相关操作——五种方式给奇数项li标签设置样式 demo演示: 1 2 3 4 5 6 7 // 详解: 通常我们为多个li添加样式时常用的是使用filter,但我们在第三节中可以看到fil ...

  5. Redhat Linux挂载NTFS格式的移动硬盘

    Redhat Linux挂载NTFS格式的移动硬盘 1. 选择下载ntfs-3g的源码包或rpm包 http://www.tuxera.com/community/open-source-ntfs-3 ...

  6. JS开发调试

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

  7. 【百度地图API】暑假放假回老家——城市切换功能

    原文:[百度地图API]暑假放假回老家--城市切换功能 任务描述: 酸奶小妹放寒假啦,要从北京呼啦一下飞回重庆呢.现在百度地图API上不能直接切换城市,怎么办呢? 如何实现: 利用API先搜索到要去城 ...

  8. 访问Ice-Pick Lodge:假设公众筹款网站Kickstarter在成功

    Xsolla非常高兴採訪了来自莫斯科的工作室 Ice-Pick Lodge的Golubeva.数天前,该公司已成功在Kickstarter上募集资金,创造出最知名的游戏"Pathologic ...

  9. ASP.NET vNext (一)- 基本概念和环境配置

    ASP.NET vNext (一)- 基本概念和环境配置 转发:微软MVP 卢建晖 的文章,希望对大家有帮助. 编者语:时代在变,在csdn开博一年就发了那么的两篇文章,无论是什么原因都觉得有愧了.但 ...

  10. [Unity3D]Unity3D游戏开发Android内嵌视图Unity查看

    ---------------------------------------------------------------------------------------------------- ...