在第二种算法中,在计算每一个f(i)时,都要找出最大的f(j)(j<i)来,由于f(j)没有顺序,只能顺序查找满足aj<ai最大的f(j),如果能将让f(j)有序,就可以使用二分查找,这样算法的时间复杂度就可能降到O(nlogn)。于是想到用一个数组B来存储“子序列的”最大递增子序列的最末元素,即有
B[f(j)] = aj
在计算f(i)时,在数组B中用二分查找法找到满足j<i且B[f(j)]=aj<ai的最大的j,并将B[f[j]+1]置为ai。
#include <iostream> #include <cstdio> #include <cstring> #include <string> #include <stack> #include <queue> #include <algorithm> using namespace std; const int inf = (1<<31)-1; const int MAXN = 5e5+10; int dp[MAXN]; int a[MAXN]; int b[MAXN]; int main() { int n; while(~scanf("%d",&n)){ memset(dp,0,sizeof(dp)); for(int i=1;i<=n;i++) scanf("%d",&a[i]); b[0] = -inf; b[1] = a[1]; int l,m,r,len=1; for(int i=2;i<=n;i++){ l = 0; r = len; while(l<=r){ m = (l+r)>>1; if(a[i]>b[m])l=m+1; else r = m-1; } b[l] = a[i]; if(l>len)len++; } cout<<len<<endl; } return 0; } // 9 2 1 5 3 6 4 8 9 7