最长递增子序列O(N^2),O(N log(N))
来源:互联网 发布:php.ini file uploads 编辑:程序博客网 时间:2024/04/30 05:50
O(N log(N))解法以前见过,忘记了,面试题里发现出现过,复习一下~
问题描述:给出一个长度为n的数字序列,求其中最长的递增的子序列。
子序列可以不连续。
解法1 O(N^2)
维护一个数组dp[],dp[i]表示的是输入数据arr[]中,以arr[i]结尾的最长递增子序列的最大长度
然后枚举终点i,用终点之前的j,并且满足arr[j]<arr[i] &&dp[j]+1>dp[i]时更新dp[i]即可.
#include<stdio.h>int main(){ int n,t; int arr[1111]; int dp[1111]; scanf("%d",&t); while(t--){ scanf("%d",&n); for(int i=1;i<=n;i++){ scanf("%d",&arr[i]); } dp[1]=1; int ans=1; for(int i=2;i<=n;i++){ dp[i]=1; for(int j=1;j<i;j++){ if(arr[i]<=arr[j]&&dp[i]<dp[j]+1){ dp[i]=dp[j]+1; if(dp[i]>ans)ans=dp[i]; } } } printf("%d\n",ans); }}
解法2 O(N log(N))
维护一个数组c,c[i]记录的是"对于当前状态下"长度为i的最长递增子序列的终点的最小数字
开始时只有c[0]=min_INF,其他的c[x]=max_INF 枚举i
i=1; 现在要计算c[1],c[1]被arr[1]更新,因为arr[1]>c[0].
i=2; 我们只需要考虑arr[2]是否大于c[1]和c[0](因为我们目前只有这2个值)
如果arr[2]>c[1]那么c[2]=arr[2],否则(arr[2]一定大于c[0],因为c[0]=min_INF)看arr[2]是否可以更新c[1]
i=3; 考虑arr[3]是否大于c[2],c[1],c[0],
如果arr[3]>c[2]那么c[3]=arr[3],否则
如果arr[3]>c[1]那么c[2]=min(c[2],arr[3])否则c[1]=min(c[1],arr[3])
i=4.....
可以看出每次只需要找到最后一个小于arr[i]的c[x],
而在更新时c数组中新加入的值一定是比之前最大的还要大
而对之前的数进行更新时,也是在最一个最远的位置(之前的数比他小,之后的数比他大)进行更新,也就是说c数组是单调的
所以我们在对于任何一个arr[i]对c进行更新位置查找时,可以二分.
最终最大的非max_INF 的c[x]的x就是结果了。
#include<stdio.h>#include<string.h>int arr[1111],c[1111];int get(int str[],int ed,int key){ int left=0,right=ed,mid; while(right>=left){ mid=(left+right)/2; if(c[mid]<=key){ left=mid+1; }else right=mid-1; } return left;}int main(){ int t,INF=0x7F7F7F7F,n; scanf("%d",&t); while(t--){ scanf("%d",&n); for(int i=1;i<=1;i++)scanf("%d",&arr[i]); memset(c,INF,sizeof(c)); c[0]=-INF; for(int i=1;i<=n;i++){ int now=get(arr,i-1,arr[i]); if(arr[i]<c[now])c[now]=arr[i]; } for(int i=n;i>=1;i--){ if(c[i]!=INF){ printf("%d\n",i);break; } } }}
- 最长递增子序列O(N^2),O(N log(N))
- 最长递增子序列 O(n^2) 与 O(nlogn)
- 最长递增子序列O(n^2)版
- 最长单调递增子序列(O(n^2))
- 动态规划解最长递增子序列(O(n^2))
- 1134 最长递增子序列(时间复杂度O(n*log(n))
- 题目:[NOIP1999]拦截导弹(最长非递增子序列DP) O(n^2)和O(n*log(n))的两种做法
- 杭电1257(最长递增子序列O(N*N)+O(N*logN))
- NYOJ 17 (最长单调递增子序列) O (n*n) + O(n*lgn)
- 用O(nlog(n)实现最长递增子序列问题
- 51nod_1134 最长递增子序列(O(n*logn))
- 最长递增子序列问题,O(N*logN)实现
- 最长上升子序列O(n^2)
- 最长递增子序列O(n^2)算法和O(nlogn)算法
- 最长递增子序列的求解(O(n*n),O(nlogn))——动态规划
- ACM最长单调递增子序列问题(动态规划)o(n*n)C++实现
- ACM最长单调递增子序列问题(动态规划)o(n*n)C++实现
- 最长公共递增子序列O(n^2)模板——ZOJ2432解题报告- -
- Maven使用Cargo实现自动化部署
- Unique Binary Search Trees
- 获取网络时间
- Java properties | FileNotFoundException: properties (系统找不到指定的文件。)
- C++迭代器:const_iterator和const形式的iterator有什么区别?
- 最长递增子序列O(N^2),O(N log(N))
- lca相关
- 代码示例函数隐藏、覆盖、重载
- 杭电 HDU 1039 Easier Done Than Said?
- MapReduce编程教训
- android ListView 学习(1)
- 溢出导致Sigabrt
- Android数据库升级
- 揭秘:乔布斯如何让才华横溢的工程师们效忠