最长上升子序列的nlogn算法实现(用栈)
来源:互联网 发布:js正则表达式 i g 编辑:程序博客网 时间:2024/05/17 03:00
最长上升子序列的nlogn算法实现(用栈)
大体算法思想是设置一个栈,数据结构里严格意义上的栈是后进先出,但是这里的栈中间有稍微不一样的地方在于中间的元素也会被覆盖掉,算法过程是,第一个元素入栈,以后没读取一个元素t,如果t比栈顶元素的大,那么就入栈。如果比它小,那么就用二分搜索的方法在栈里面找到这样一个元素stack[i],使得stack[i]>t并且stack[i-1](如果有的话)<t,然后就用t去更新这个stack[i]元素。举个例子,如果输入一下数据
5 9 4 1 3 7 6 7
那么栈的变化过程为:
5
5 9
4 9 //用4更新了5
1 9
1 3
1 3 7
1 3 6
1 3 6 7
最后的结果,最长递增子序列的长度就是栈的大小,这里是4。要注意的是最后栈里的元素并不就一定是所求的序列,例如如果输入
2 5 1
那么最后得到的栈应该是
1 5
而实际上要求的序列是
2 5
至于要怎么求这个序列。。。这个。。。看了讲解之后自己还是没研究透彻。。。哈哈,有空再说了。算法的正确性没有经过严格的证明,不过想想看应该是对的吧,哈哈,偷懒了。
代码(写得有些丑陋的):
/*
习题 33:最长递增子序列★★★
问题描述:
所谓子序列,就是在原序列里删掉若干个元素后剩下的序列,以字符串"abcdefg"为例子,去掉bde得到子序列"acfg"
现在的问题是,给你一个数字序列,你要求出它最长的单调递增子序列。
输入:
多组测试数据,每组测试数据第一行是n(1<=n<=10000),下一行是n个比1e9小的非负整数
输出:
对于每组测试数据输出一行,每行内容是最长的单调递增子序列的长度
样例输入:
5
1 2 4 8 16
5
1 10 4 9 7
9
0 0 0 1 1 1 5 5 5
样例输出:
5
3
3
难度:normal
*/
5 9 4 1 3 7 6 7
那么栈的变化过程为:
5
5 9
4 9 //用4更新了5
1 9
1 3
1 3 7
1 3 6
1 3 6 7
最后的结果,最长递增子序列的长度就是栈的大小,这里是4。要注意的是最后栈里的元素并不就一定是所求的序列,例如如果输入
2 5 1
那么最后得到的栈应该是
1 5
而实际上要求的序列是
2 5
至于要怎么求这个序列。。。这个。。。看了讲解之后自己还是没研究透彻。。。哈哈,有空再说了。算法的正确性没有经过严格的证明,不过想想看应该是对的吧,哈哈,偷懒了。
代码(写得有些丑陋的):
/*
习题 33:最长递增子序列★★★
问题描述:
所谓子序列,就是在原序列里删掉若干个元素后剩下的序列,以字符串"abcdefg"为例子,去掉bde得到子序列"acfg"
现在的问题是,给你一个数字序列,你要求出它最长的单调递增子序列。
输入:
多组测试数据,每组测试数据第一行是n(1<=n<=10000),下一行是n个比1e9小的非负整数
输出:
对于每组测试数据输出一行,每行内容是最长的单调递增子序列的长度
样例输入:
5
1 2 4 8 16
5
1 10 4 9 7
9
0 0 0 1 1 1 5 5 5
样例输出:
5
3
3
难度:normal
*/
#include <cstdio>#define MAXN 10000long long stack[MAXN];int n;long long t;int top;int main(){ int i; int mid,high,low; while(scanf("%d",&n)==1 && n!=0) { scanf("%lld",&stack[0]); top=1; for(i=1;i<n;i++) { scanf("%lld",&t); if(t>stack[top-1]) //一 stack[top++]=t; if(t==stack[top-1]) //二 continue; else //三 { low=0; high=top-1; while(true) { mid=(low+high)/2; if(stack[mid]>=t && (mid==0 || stack[mid-1]<t)) { stack[mid]=t; break; } if(stack[mid]<t) low=mid+1; else high=mid-1; } } } printf("%d\n",top); } return 0;}
- 最长上升子序列的nlogn算法实现(用栈)
- 最长上升子序列(nlogn算法)
- nlogn的最长上升子序列的算法(LIS)
- nlogn的LIS(最长上升子序列)算法讲解
- 最长上升子序列nlogn算法
- 最长上升子序列nlogn算法
- 最长上升子序列NLOGN算法
- 最长上升子序列O(nlogn)算法
- 最长上升子序列----nlogn算法-模板
- bsoj2234 最长上升子序列nlogn算法
- 最长上升子序列nlogn算法
- 最长上升子序列nlogn算法
- 最长上升子序列nlogn算法
- 最长上升子序列nlogn算法
- 最长上升子序列nlogn算法
- 最长上升子序列nlogn算法
- 最长上升子序列nlogn算法
- 最长上升子序列nlogn算法
- 直接拿来用!超实用的Java数组技巧攻略
- Install Linux Malware Detect (LMD) in RHEL, CentOS and Fedora
- Android 异步加载网络图片并缓存到本地 软引用 学习分享
- 今天立志成为黑马的一员
- C语言中sizeof 与strlen 区别
- 最长上升子序列的nlogn算法实现(用栈)
- 为什么选择java
- BNUOJ27888:Baby Me
- 字符串替换
- HEVC码流简单分析
- Ubuntu - 修改默认引导顺序
- linux-可重入与不可重入函数
- uva 11825 - Hackers' Crackdown
- Linux Directory Structure and Important Files Paths Explained