最大上升子序列,最大下降子序列,最大非增子序列,最大非减子序列
2017-12-23 11:50
246 查看
http://www.cnblogs.com/eastblue/p/7612134.html 原地址,搬运一下方便看
最大上升子序列,最大下降子序列,最大非增子序列,最大非减子序列
For example,{1,5,2,4,3,5,6,4,7}的最大上升子序列是{1,2,3,5,6,7}长度为6现已知原序列a[],如何求其最大上升子序列,最大下降子序列,最大非增子序列,最大非减子序列的长度?
下面贴出两种方法:1.dp, 2.贪心+二分
下面详解第二种贪心+二分,时间复杂度位O(nlongn)的算法(注意:下面以严格上升子序列为例,请把上面代码中的lower_bound换成upper_bound):
首先,
b[maxn] b[k] 记录前i个数中的长度为k+1的所有上升子序列中最后一位最小的值
记录下最后一位最小的值,是为了能有更大的上升空间
比如序列{1,3,2,3,4}
前三个数{1,3,2}中长度为2的上升子序列有{1,3}和{1,2},分别对应的b[1](长度为1+1=2的上升子序列的最后一位的值)为3,2,明显,选2这个较小的可以给后面的序列留下更多的上升空间,选2可以是{1,2,3,4}而选3只能是{1,3,4},b[k]的值尽可能小,
这就是其贪心的思想
b数组一定是严格上升的,因为长度为i的最后一位最优不可能比长度为i-1的最后一位小。
既然b数组是有序的,接下来就能用二分的方法了
先将b的元素最大化,然后将将原序列a的元素一个一个插入到b中合适的位置--b中第一个大于a[i]的位置,这样如果a[i]能够大于b[k]说明a[i]能够放在b[k](其实是b[k]的值对应的原序列元素)的后面,而到了第一个大于a[i]的位置,
假设那个位置x上的的值为y(y可以为inf),a[x]=y>a[i],再根据上面贪心的思想,何不把结尾换为更小的值a[i]呢,即b[x]=a[i];
这样插入完所有的a[i](其实就是将a[i]插在能以它为结尾的最大子序列长度的位置上),一重循环到最后一个b[i]!=inf,然后这个i+1就是最大上升子序列的长度
接下来再以{1,5,2,4,3,5,6,4,7}为例,画个图让大家理解理解:
相关文章推荐
- 最大上升(下降)子序列 小节
- 算是第一个抄的DP 最大上升(下降)子序列
- tyvj 1208 最长不下降子序列2 求序列b1,b2,b3,…,bm中所有长度(n)最大上升子序列的个数
- 波浪子序列(最大上升下降子序列)
- hdu 1087 上升子序列最大和
- hdu 1087最大上升子序列的和
- 拦截导弹(规律:下降子序列的个数等于最长上升子序列的长度)
- 蓝桥杯算法训练拦截导弹【最长上升子序列 & 最长非下降子序列nlogn 和 n^2】
- poj_1952最大下降子序列,统计个数
- hdoj 1069 Monkey and Banana(上升子序列最大和)
- Codeforces Round #335 (Div. 2)-Sorting Railway Cars(求连续的上升序列的最大值)
- POJ 1836 Alignment(DP max(最长上升子序列 + 最长下降子序列))
- 动态规划-3003-序列的最大上升子序列
- Lintcode 114.最大上升连续子序列
- 3532:最大上升子序列和(最长上升子序列变式)
- poj_1952最大下降子序列,统计个数
- 最大上升子序列的和
- poj_1952最大下降子序列,统计个数
- ECNU2958最大上升子序列(动态规划)
- 找一个数组的最大上升子序列(允许不连续)