算法实践--最长递增子序列(Longest Increasing Subsquence)
什么是最长递增子序列(Longest Increasing Subsquence)
对于一个序列{3, 2, 6, 4, 5, 1},它包含很多递增子序列{3, 6}, {2,6}, {2, 4, 5}, {1}
其中最长的递增子序列是{2, 4, 5}
问题:对于长度为N的矢量D,如何找到它的最长递增子序列
一个简单的算法
for (i=N; i>0; --i) {. 找到所有长度为i的子序列; //复杂度为(N!)/(i!)(N-i)! O(exp(N))
. 判断是否其中有一个为递增子序列
}
动态规划算法
基本思想:将一个复杂问题,分解为更小的子问题
首先定义LIS[i],表示以D[i]结尾的最长子序列
对于矢量D = {, , , , , }; LIS[]:
LIS[]:
LIS[]: ,
LIS[]: ,
LIS[]: ,,
LIS[]:
给出递推公式
LIS[0] = D[0]
LIS[i] = MAX(LIS[j] | j <i, D[j] <D[i]) + "D[i]"
解释:
当我们求LIS[i]时,对于任意j<i,LIS[j]都已知
在所有已知的LIS中,找出结尾的元素值小于D[i],长度最长的一个
然后在后面加上D[i]元素,即为LIS[i]
示例C++代码
using namespace std; void prt(vector<int>& arr, string msg = "") {
cout << msg << " ";
for (auto i: arr) {
cout << i << " ";
}
cout << endl;
} void calc_LIS(vector<int>& D) {
vector< vector<int> > L(D.size()); // The longest increasing subsequence ends with D[i] L[].push_back(D[]); for (int i=; i<D.size(); i++) {
for(int j=; j<i; j++) {
if ( (D[j] < D[i]) && ( L[i].size() < L[j].size() ) ) {
L[i] = L[j];
}
}
L[i].push_back(D[i]);
} for (auto x: L) {
prt(x);
}
} int main() {
int a[] = {, , , , , };
vector<int> arr(a, a + sizeof(a)/sizeof(a[])); prt(arr, "Data In:");
calc_LIS(arr); return ;
}
复杂度分析
时间复杂度是O(N^2)
动态规范的基本思想是以一定的空间开销,显著缩短时间开销
算法实践--最长递增子序列(Longest Increasing Subsquence)的更多相关文章
- 算法实践--最长公共子序列(Longest Common Subsquence)
什么是最长公共子序列 X=ACCG Y=CCAGCA 长度为1的公共子序列: {A} {C} {G} 长度为2的公共子序列:{AC} {CC} {CG} {AG} 长度为3的公共子序列:{ACG} 长 ...
- 最长递增子序列(Longest increasing subsequence)
问题定义: 给定一个长度为N的数组A,找出一个最长的单调递增子序列(不要求连续). 这道题共3种解法. 1. 动态规划 动态规划的核心是状态的定义和状态转移方程.定义lis(i),表示前i个数中以A[ ...
- 【转】动态规划:最长递增子序列Longest Increasing Subsequence
转自:https://www.cnblogs.com/coffy/p/5878915.html 设f(i)表示L中以ai为末元素的最长递增子序列的长度.则有如下的递推方程: 这个递推方程的意思是,在求 ...
- 最长递增子序列(Longest Increase Subsequence)
问题 给定一个长度为N的数组,找出一个最长的单调自增子序列(不一定连续,但是顺序不能乱).例如:给定一个长度为6的数组A{5, 6, 7, 1, 2, 8},则其最长的单调递增子序列为{5,6,7,8 ...
- 300最长上升子序列 · Longest Increasing Subsequence
[抄题]: 往上走台阶 最长上升子序列问题是在一个无序的给定序列中找到一个尽可能长的由低到高排列的子序列,这种子序列不一定是连续的或者唯一的. 样例 给出 [5,4,1,2,3],LIS 是 [1,2 ...
- [Swift]LeetCode300. 最长上升子序列 | Longest Increasing Subsequence
Given an unsorted array of integers, find the length of longest increasing subsequence. Example: Inp ...
- [Swift]LeetCode329. 矩阵中的最长递增路径 | Longest Increasing Path in a Matrix
Given an integer matrix, find the length of the longest increasing path. From each cell, you can eit ...
- nlog(n)解动态规划--最长上升子序列(Longest increasing subsequence)
最长上升子序列LIS问题属于动态规划的初级问题,用纯动态规划的方法来求解的时间复杂度是O(n^2).但是如果加上二叉搜索的方法,那么时间复杂度可以降到nlog(n). 具体分析参考:http://b ...
- 动态规划--最长上升子序列(Longest increasing subsequence)
前面写了最长公共子序列的问题.然后再加上自身对动态规划的理解,真到简单的DP问题很快就解决了.其实只要理解了动态规划的本质,那么再有针对性的去做这方的题目,思路很快就会有了.不错不错~加油 题目描述: ...
随机推荐
- Cassandra.yaml 配置详解
cluster_name 设置Cassandra集群的名称. 在Cassandra集群中,每一台服务器都必须具备相应的集群的名称.如果名称不一致,则当前Cassandra服务器无法加入集群. init ...
- 2015-10-19 sql1
SQL SERVER(一) 一.设置登陆验证 1.右键点击数据库->属性->安全性设置密码登陆 2.数据库下找到安全性->登录名->sa,右键点击sa->属性(修 ...
- debug makefile 及 lint 软件质量软件
make -d should give you more than enough information to debug your makefile. Be warned: it will take ...
- keepalived高可用集群。
keepalived故障切换转移原理1vrrp协议:(vritual router redundancy protocol)虚拟路由冗余协议,2故障转移.keepalived三大功能1实现物理高可用, ...
- oracle中 trunc 处理日期的用法
方法/步骤 1 select trunc(sysdate) from dual 结果是 截止到当日 不设置,默认是截止到”日“ 2 select trunc(sysdate,'year') fr ...
- day37-多进程多线程二-锁
Lock组件 当我们用多进程来读写文件的时候,如果一个进程是写文件,一个进程是读文件,如果两个文件同时进行,肯定是不行的,必须是文件写结束以后,才可以进行读操作.或者是多个进程在共享一些资源的时候,同 ...
- PHP_CodeSniffer 安装和phpstorm配置
安装 1.mac安装 sudo pear install PHP_CodeSniffer phpstorm配置 1. 点击菜单:File->Settings 或 按快捷键 Ctrl+Alt+S ...
- 福大软工 · BETA 版冲刺前准备(团队)
BETA 版冲刺前准备 队名:第三视角 作业链接 组长博客 应作业要求为了更加顺利地开展beta版本的冲刺,上次的alpha版本展示后,我们组对之前开发过程中存在的各种问题进行了全面的讨论,并对其进行 ...
- 一个神奇的???whatever~~
一个神奇的类,用来封装消息数据,统一数据传递接口,从unity引擎源码拷贝而来. #include <iostream> #include <assert.h> #includ ...
- 2 第一个Django应用 第1部分(数据库与模型)
目标应用: 一个公开的网站,可以让访客查看投票的结果并让他们进行投票. 一个后台管理网站,你可以添加.修改和删除选票. 查看django版本 python -c "import django ...