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         else
30         {
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 }
时间: 2024-12-24 01:30:24

TYVJ1254的相关文章