动态规划:最大上升子序列
来源:互联网 发布:mysql deadlock 编辑:程序博客网 时间:2024/03/29 06:37
一个数的序列bi,当b1 < b2 < … < bS的时候,我们称这个序列是上升的。对于给定的一个序列(a1, a2, …,aN),我们可以得到一些上升的子序列(ai1, ai2, …, aiK),这里1 <= i1 < i2 < … < iK <=N。
比如,对于序列(1, 7, 3, 5, 9, 4, 8),有它的一些上升子序列,如(1, 7), (3, 4, 8)等等。这些子序列中最长的长度是4,比如子序列(1, 3, 5, 8).
问题描述如上,那么如何实现求解一个未知序列的最大上升子序列呢?首先应该进行问题分解,依旧以(1, 7, 3, 5, 9, 4, 8)为例,maxs[i]表示以i为终点的最大上升子序列长度,这里从1开始。
- 以第一位为终点的子序列,只有1个,maxs[1] = 1;
- 以第二位为终点的子序列,(1,7),maxs[2] = 2;
- 以第三位为终点的子序列,(1,7,3),maxs[3] = 2;
- …
以第n位为终点的子序列,maxs[n] = t(t未知);
那么现在问题就可以简化为求max数组中的最大值。即为最大上升子序列的长度。
现在重点来了,我们如何来求得maxs呢。当我们以第n位为终点时,他的最大上升子序列maxs[n]为在第i(1 < i < n-1)位中,所有满足arr[i] < arr[n]的maxs[i]中的最大值加1。
现在,问题可以说已经迎刃而解,那就让我们来通过美丽的代码实现他吧。
function maxChildlen(arr) { var maxs = [], N = arr.length, max = 0, flag; for (var i = 0; i < N; i++) { flag = 0; maxs[i] = 1; for (var j = 0; j < i; j++) { if (arr[j] <= arr[i] && maxs[j] > flag) { flag = maxs[j]; } } maxs[i] = flag + 1; if (maxs[i] > max) { max = maxs[i]; } } return max; }
算法改进:
从第一位开始,第一位进入数组b中;
第二位如果大于b[0],直接入栈b[1],否则,替换b[0];
第三位,如果大于b的最后一位,则入栈b,否则,在b中寻找大于arr[3]的最小位(下界),然后将其替换掉。
…
以此类推,第N位与b[b.length]进行比较,如果大于b[b.length];直接入栈b,否则在b中寻找大于arr[N]的下界,将其替换。
…
最后b的长度就是最大上升子序列的长度。
这样一来,我们可以将原来的两层循环,分为一个循环和一个查找,查找我们采用二分查找,从而将时间复杂度降为logn; 这样,算法总的时间复杂度有logn^2优化为nlogn。
贴代码:
//最大上升子序列 function maxlen(arr) { //存放最大上升子序列 var maxarr = [], N = arr.length, len = 0; //最小长度为1 maxarr[len] = arr[len]; for (var i = 1; i < N; i++) { if (arr[i] > maxarr[len]) { maxarr[++len] = arr[i]; } else { if ((len - 1) >= 0 && arr[i] >= maxarr[len - 1]) { maxarr[len] = arr[i] } } } return maxarr; }
Nice!
- 动态规划:最大上升子序列
- 动态规划--最大上升子序列和
- 动态规划:最大上升子序列和
- 【动态规划】求最大上升子序列
- 动态规划-3003-序列的最大上升子序列
- poj 2533 【动态规划】【最大上升子序列】
- 题目1480:最大上升子序列和:动态规划
- hdu 1087 (最大上升子序列和)动态规划
- |NOIOJ|动态规划|3532:最大上升子序列和
- 动态规划练习一 13:最大上升子序列和
- 动态规划练习一 13:最大上升子序列和
- 动态规划练习题-13(最大上升子序列和)
- 动态规划练习一—13最大上升子序列
- ACM-动态规划13-最大上升子序列和
- 动态规划练习13:最大上升子序列和
- 动态规划练习--13(最大上升子序列和)
- 动态规划―最大上升子序列和
- 动态规划—13最大上升子序列和
- 构造函数初始化列表
- 用LoadRunner分析资源占用率
- 图解Linux命令之--declare命令
- 单类模式
- E
- 动态规划:最大上升子序列
- UDP之socket通信
- ToLua LuaFramework 使用实战[1]-代码热更新
- Unity3D引擎之渲染技术系列三
- cvpr2016-master-pascal调参
- NYOJ547_Interesting Punch-Bowl_优先队列
- 2017 华为软件精英挑战赛——思路、算法简介
- SourceTree安装教程和GitLab配置详解
- bootstrap-table 表头,和内容对齐问题