首页 > 代码库 > TYVJ1254
TYVJ1254
最长不降子序列,O(n^2)算法能超时超到明年
需要o(nlogn)算法(CMI)
这个问题利用到了辅助数组d[i],这里姑且称它为栈,因为对该
数组的操作像是栈的操作,d[i]表示长度为i的不降子序列中最小
的最后元素,最后栈的长度就是最长不降子序列的长度
当循环到a[i]的时候和栈顶元素s比较,如果s<=a[i],就是说a
[i]比最长的不降子序列的最小的那个元素大或等于,那么把a
[i]放到栈顶,子序列也就加了1
如果s>a[i]则在栈中找最大的j使得d[j]<=a[i],然后将j+1替换
为a[i],因为栈中的元素都是单调递增的(随便想一下就知道),
所以可以用二分求上限求得,这样的查找的时间复杂度就是
o(logn),总的复杂度就是o(nlogn)
重点就是二分求上限,LRJ的小白书上就有
1 //288 2 #include <cstdio> 3 #include <cstring> 4 #include <iostream> 5 #include <algorithm> 6 using namespace std; 7 const int maxn = 30005; 8 int d[maxn],a[maxn],cnt = 0; 9 int up_search(int l,int r,int val)10 {11 while(l<r)12 {13 int m = (l+r)>>1;14 if(d[m]<=val)l = m+1;15 else r = m;16 //printf("%d\n",cnt++);17 }18 return l;19 }20 int main()21 {22 //freopen("in.txt","r",stdin);23 int n;24 cin>>n;25 for(int i = 1;i<=n;++i)scanf("%d",a+i);26 int r = 0;27 for(int i = 1;i<=n;++i)28 if(!r)d[++r] = a[i];29 else30 {31 if(a[i]>=d[r])d[++r] = a[i];32 else d[up_search(1,r,a[i])] = a[i];33 }34 printf("%d\n",r);35 return 0;36 }
TYVJ1254
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。