问题:

Given an array of N integer, find the length of the longest increasing subsequence.

For example, given [1,-5,4,5,10,-1,-5,7], the longest increasing subsequence is length 4.(1,4,510)

思路:

1、枚举

枚举数组所有的子序列,然后判断它们是否为递增子序列(回溯法)。

2、转化

将数组排序,然后找出新数组和旧数组的最长公共子序列LCS。

(关于最长公共子序列,参考:http://www.cnblogs.com/AndyJee/p/4469196.html)

3、动态规划

假设数组为A,len[i] 表示以第 i 个元素为结尾(即第i个元素为最大)的最长递增子序列的长度;

求len[i],可以先求以前面i-1个元素结尾的最长递增子序列,如果A[i]比前面A[0...i-1]中某个元素k小,那么就可以在相应的len[k]上加1,当然是最大的len[k];

详见http://blog.csdn.net/kenby/article/details/6804720

4、优化

上述方法在求len[i]的时候, 要从a[1], ... a[i-1]中找出所有比 a[i] 小的元素,而a[1], ... a[i-1]是无序的,查找速度比较慢。

引出数组 f[k] 表示长度等于k的递增子序列中最末尾的元素, 长度越长的序列,其末尾元素也越大,所以f[k]是递增的。

实例 <1, 3, 4, 2, 7>

len[1] = 1, f[1] = a[1] = 1

len[2] = 2, f[2] = a[2] = 3

len[3] = 3, f[3] = a[3] = 4

len[4] = 2, f[2] = a[4] = 2 ( 更新了f[2] )

那么,如何求len[5] 呢?

f[1] = 1, f[2] = 2, f[3] = 4, a[5] = 7,

找出末尾元素比a[5]小,而且长度最长的递增子序列,此例中,

f[3] = 4 表示长度等于3的子序列,其末尾元素为4,这个子序列的长度最长。

a[5]加上此序列形成的新序列长度为4, 然后更新f[4] = a[5] = 7,表示长度等于4的子序列,其末尾元素等于7

在上面的步骤中,找出末尾元素比a[i]小,而且长度最长的子序列,其实就是对于f[1], ...f[k], 从后往前找,第一个比a[i]小的元素就是长度最长的子序列。查找的时候可以用二分查找方法,故更快。

代码:

1、动态规划

#include <iostream>
#include <vector>
using namespace std;unsigned int LISS(const int array[], size_t length, vector<int> &result)
{unsigned int liss[length];unsigned int pre[length];for(int i=0;i<length;++i){liss[i]=1;pre[i]=i;}int k=0;int max=1;for(int i=1;i<length;++i){for(int j=0;j<i;++j){if(array[j]<array[i] && liss[j]+1>liss[i]){liss[i]=liss[j]+1;pre[i]=j;if(max<liss[i]){max=liss[i];k=i;}}}}//    i = max - 1;while(pre[k]!=k){
//        result[i--] = array[k];result.push_back(array[k]);k=pre[k];}//result[i] = array[k];result.push_back(array[k]);return max;
}int main()
{int A[]={1,-5,4,5,10,-1,-5,7};int len=sizeof(A)/sizeof(A[0]);vector<int> result;cout << LISS(A,len,result) << endl;for(int i=0;i<result.size();i++)cout<<result[i]<<' ';cout<<endl;
}

2、优化

#include <iostream>
#include <vector>
using namespace std;unsigned int LISS(const int array[], size_t length, vector<int> &result)
{unsigned int liss[length];unsigned int pre[length];unsigned int f[length];for(int i=0;i<length;++i){liss[i]=1;pre[i]=i;f[i]=0;}int k=0;int max=1;f[max]=0;for(int i=1;i<length;++i){for(int j=max;j>=1;--j){if(array[f[j]]<array[i]){liss[i]=j+1;pre[i]=f[j];if(f[liss[i]]!=0){int old=array[f[liss[i]]];if(array[i]<old)f[liss[i]]=i;}elsef[liss[i]]=i;if(max<liss[i]){max=liss[i];k=i;}break;}}}//    i = max - 1;while(pre[k]!=k){
//        result[i--] = array[k];result.push_back(array[k]);k=pre[k];}//result[i] = array[k];result.push_back(array[k]);return max;
}int main()
{int A[]={1,3,4,2,7};int len=sizeof(A)/sizeof(A[0]);vector<int> result;cout << LISS(A,len,result) << endl;for(int i=0;i<result.size();i++)cout<<result[i]<<' ';cout<<endl;
}

在线测试OJ:

http://www.nowcoder.com/questionTerminal/585d46a1447b4064b749f08c2ab9ce66

AC代码:

class AscentSequence {
public:int findLongest(vector<int> A, int n) {vector<int> dp(n);vector<int> f(n);dp[0]=1;f[0]=A[0];int left,right,mid;int count=0;int lmax=1;for(int i=1;i<n;i++){left=0;right=count;while(left<=right){mid=left+((right-left)>>1);if(A[i]>=f[mid])left=mid+1;elseright=mid-1;}f[left]=A[i];if(left>count)count=left;dp[i]=left+1;if(lmax<dp[i])lmax=dp[i];}return lmax;       }
};

class AscentSequence {
public:int findLongest(vector<int> A, int n) {int len=A.size();if(len<=1)return len;vector<int> mLen(n,1);int lMax=1;for(int i=1;i<n;i++){for(int j=0;j<i;j++){if(A[i]>A[j] && mLen[j]+1>mLen[i])mLen[i]=mLen[j]+1;if(mLen[i]>lMax)lMax=mLen[i];}}return lMax;}
};

转载于:https://www.cnblogs.com/AndyJee/p/4703332.html

(算法)最长递增子序列相关推荐

  1. 跟着编程之美学算法——最长递增子序列(转)

    之前学习了动态规划中最基本的问题,最长公共子序列,具体解法,见前前一篇博客: http://www.cnblogs.com/liyukuneed/archive/2013/05/22/3090597. ...

  2. 动态规划算法 | 最长递增子序列

    通过查阅相关资料发现动态规划问题一般就是求解最值问题.这种方法在解决一些问题时应用比较多,比如求最长递增子序列等. 有部分人认为动态规划的核心就是:穷举.因为要求最值,肯定要把所有可行的答案穷举出来, ...

  3. 动态规划算法04-最长递增子序列问题

    最长递增子序列问题 简述 经典的动态规划问题. 问题描述 给定一个序列,求解其中长度最长的递增子序列. 问题分析 这种可以向下查询答案的很容易想到动态规划的解法. 要求长度为i的序列Ai={a1,a2 ...

  4. JavaScript实现LongestIncreasingSubsequence最长递增子序列算法(附完整源码)

    JavaScript实现LongestIncreasingSubsequence最长递增子序列算法(附完整源码) dpLongestIncreasingSubsequence.js完整源代码 dpLo ...

  5. 动态规划算法-04最长递增子序列问题

    最长递增子序列问题 简述 经典的动态规划问题. 问题描述 给定一个序列,求解其中长度最长的递增子序列. 问题分析 这种可以向下查询答案的很容易想到动态规划的解法. 要求长度为i的序列Ai={a1,a2 ...

  6. 最长递增子序列_python_算法与数据结构

    周末了,实验室的网速还是不给力啊,不知道doctors都在干啥,,,最近都在做算法作业,昨天晚上看了一部电影<将爱进行到底>,刚打开电影没多久就听到了很熟悉的旋律,让我很是惊讶,这竟然就是 ...

  7. 计算机算法设计与分析 最长递增子序列

    求一个字符串的最长递增子序列的长度.设计基于动态规划思想的算法. 如:dabdbf最长递增子序列就是abdf,长度为4 输入第一行一个整数0<n<20,表示有n个字符串要处理,随后的n行, ...

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

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

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

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

  10. 最长递增子序列 O(NlogN)算法

    最长递增子序列 O(NlogN)算法 今天回顾WOJ1398,发现了这个当时没有理解透彻的算法. 看了好久好久,现在终于想明白了. 试着把它写下来,让自己更明白. 最长递增子序列,Longest In ...

最新文章

  1. 基于Picture Library创建的图片文档库中的上传多个文件功能(upload multiple files)报错怎么解决?...
  2. c primer plus 5 读书笔记1
  3. mysql驱动(github上的)
  4. 【Google Play】APK 扩展包 ( 2021年09月02日最新处理方案 | 制作 APK 扩展包 | 上传 APK 扩展包到 Google Play | APK 扩展文件上传时机 )
  5. Python分析年度爆款“网抑云”热评,看看哪些文案触动了你的内心世界?
  6. 程序员如何才配拥有姓名?
  7. 【BZOJ-13361337】Alie最小圆覆盖 最小圆覆盖(随机增量法)
  8. 获取高程数据以及转灰度图和裁剪操作
  9. 通过console口连接AC控制器,修改WiFi密码
  10. 【黑马程序员】-c函数
  11. macbook桌面的文件突然消失的解决方案
  12. Fwcms模板建站常见问题整理合集解答
  13. 当面试官问:JS中原始类型有哪些?
  14. IAR下载出现错误An error occurred while retrieving GDI features: gdi-error [40201]
  15. 单片机入门教程:第七章 1602LCD液晶显示模块
  16. StartSonar.bat启动闪退问题
  17. 普元中间件Primeton AppServer6.5部署SuperMap iServer
  18. Archive一个Microsoft Teams里创建的Team
  19. Android 出现应用未安装
  20. 赵云传 java游戏_谁说国产游戏没希望?中国最优秀的20大游戏盘点

热门文章

  1. 使用ETag识别ajax,如何使用jQuery AJAX请求访问ETag头?
  2. C# Android wifi控制灯,求助如何在基于安卓通过WiFi与Arduino通信,实现对LED灯的控制。...
  3. android 的监控讲解,java android网络监测详解
  4. java中io流是类吗_Java中的IO流
  5. 计算机网络基础:网络标准相关知识介绍
  6. Linux中常见的环境变量笔记
  7. c#中常用集合类和集合接口之集合类系列
  8. 数据库 CURD测试题【简单】
  9. 写给前端新手看的一些模块化知识
  10. Juniper SRX防火墙批量导入set格式配置