1 // 前面我们用(n^2)复杂度dp求了最长公共子序列 2 // 当时dp数组定义如下: 3 // dp[i]:以末尾数结尾的最长公共子序列的长度 4 // 每次都利用前一次的结果,可以轻松求得以最后一个数为最结尾的最长公共子序列的长度 5 // if(a[i]>a[j] && dp[i]<=dp[j]) dp[i]=dp[j]+1; 6 7 // 现在重新定义dp[i]: 8 // dp[i]:长度为i+1的上升子序列中,末尾元素的最小值(不存在为INF) 9 // i+1? √,从0开始 10 11 #include <cstdio> 12 #include <iostream> // fill需用 13 14 using namespace std; 15 16 const int max_n = 1000+2; 17 const int max_a = 1e6+2; 18 const int INF = 1e6+10; 19 20 int n; 21 int a[max_n]; 22 int dp[max_n]; 23 24 // 一次循环+二分 25 // 复杂度只有(n*log(n)) 26 27 void solve() 28 { 29 fill(dp,dp+n,INF); 30 for(int i=0;i<n;++i) 31 { 32 *lower_bound(dp,dp+n,a[i])=a[i]; 33 } 34 int ans=lower_bound(dp,dp+n,INF)-dp; 35 printf("%d ",ans); 36 } 37 38 int main() 39 { 40 scanf("%d",&n); 41 for(int i=0;i<n;++i) 42 { 43 scanf("%d",&a[i]); 44 } 45 solve(); 46 return 0; 47 }