最长上升子序列LIS算法粗略讲解
2016-08-09 14:51
232 查看
定义:
LIS(Longest Increasing Subsequence)最长上升(不下降)子序列,有两种算法复杂度为O(n*logn)和O(n^2)。在上述算法中,若使用朴素的顺序查找在D1..Dlen查找,由于共有O(n)个元素需要计算,每次计算时的复杂度是O(n),则整个算法的时间复杂度为O(n^2),与原来算法相比没有任何进步。但是由于D的特点(2),在D中查找时,可以使用二分查找高效地完成,则整个算法时间复杂度下降为O(nlogn),有了非常显著的提高。需要注意的是,D在算法结束后记录的并不是一个符合题意的最长上升子序列!算法还可以扩展到整个最长子序列系列问题。问题描述:给出一个序列a1,a2,a3,a4,a5,a6,a7….an,求它的一个子序列(设为s1,s2,…sn),使得这个子序列满足这样的性质,s1
#include <iostream> #include <cstdio> #include <cstring> #include <cstdlib> #include <algorithm> #include <map> #include <cmath> #include <queue> using namespace std; const int maxn=1e3+10; int n,a[maxn],dp[maxn]; int main() { while(~scanf("%d",&n)) { for(int i=0;i<n;i++) { scanf("%d",a+i); dp[i]=1; } for(int i=1;i<n;i++) { for(int j=0;j<i;j++) { if(a[i]>a[j]) { dp[i]=max(dp[i],dp[j]+1); } } } int maxi=0; for(int i=0;i<n;i++) { printf("sss i=%d dp[i]=%d\n",i,dp[i]); maxi=max(maxi,dp[i]); } printf("%d\n",maxi); } return 0; }
(nlogn):维护一个一维数组c,并且这个数组是动态扩展的,初始大小为1,c[i]表示最长上升子序列长度是i的所有子串中末尾最小的那个数,根据这个数字,我们可以比较知道,只要当前考察的这个数比c[i]大,那么当前这个数一定能通过c[i]构成一个长度为i+1的上升子序列。当然我们希望在C数组中找一个尽量靠后的数字,这样我们得到的上升子串的长度最长,查找的时候使用二分搜索,这样时间复杂度便下降了。
#include <iostream> #include <cstdio> #include <cstring> #include <cstdlib> #include <algorithm> #include <map> #include <cmath> #include <queue> using namespace std; int n,a[40005],dp[40005],b[40005]; int main() { int t; scanf("%d",&t); while(t--) { scanf("%d",&n); for(int i=1;i<=n;i++) { scanf("%d",&a[i]); dp[i]=1; } int l,r,mid,maxi=0,len=0; for(int i=1;i<=n;i++) { int num=a[i]; l=1; r=len; while(l<=r) { mid=(l+r)>>1; if(num>b[mid]) l=mid+1; else r=mid-1; } b[l]=num; dp[i]=l; if(l>len) len=l; if(dp[i]>maxi) maxi=dp[i]; } printf("%d\n",maxi); } return 0; }
END!!!!!!!!!!!!!!!!!!!
相关文章推荐
- 最长上升子序列 记忆化讲解
- 最长上升子序列LIS算法实现
- 最长上升子序列LIS算法实现
- 最长上升子序列LIS算法实现
- 竞赛题目讲解-【Northeastern Europe 2002, Far-Eastern Subregion】最长上升子序列
- 最长上升子序列LIS算法实现
- LIS算法(最长上升子序列)
- C语言:最长上升子序列LIS算法实现
- LIS算法: 最长上升子序列
- nlogn的LIS(最长上升子序列)算法讲解
- 最长上升子序列——O (nlogn)算法原因解析!为什么这样可以求出来!(附带动态规划dp + 二分查找讲解)
- 【HDU 1950】Bridging signals(LIS算法求最长上升子序列)
- 优化的最长上升子序列LIS算法 O(nlogn)
- HDU 1025 Constructing Roads In JGShining's Kingdom(最长上升子序列O(nlogn))
- 动态规划——求最长下降/上升子序列
- BZOJ 3173: [Tjoi2013]最长上升子序列
- ZOJ 1076 最长上升子序列
- ZOJ - 2432 / HDU - 1423 最长公共上升子序列
- UVALive2931 POJ1631 HDU1950 ZOJ1986 Bridging signals【最长上升子序列+二分+堆栈】
- Codeforces Round #345 Div.1 D.Zip-line 动态最长上升子序列