标签:lower 超时 src splay 复杂度 logs close 基础题 pen
第1行:1个数N,N为序列的长度(2 <= N <= 50000) 第2 - N + 1行:每行1个数,对应序列的元素(-10^9 <= S[i] <= 10^9)
输出最长递增子序列的长度。
8 5 1 6 8 2 4 5 10
5
常规的解法是设dp[i]表示前i位的最长上升序列长度,然后每次更新dp[i+1]都要与[0,i]进行一次比较。
时间复杂度为O(n^2),完美超时。
想想怎么去优化呢?看看更新dp[i+1]需要比较这么多次吗?假设dp[i+1]=len,那么我们只要与值为len-1的去
进行比较,所以不妨设b[i]表示最长上升序列为i的dp数组中的最小值。
1 /*用数组b来存放最长上升序列,然后枚举数组a中元素看能否插入b数组。 2 那么b数组的大小即为所求。 3 */ 4 #include <iostream> 5 #include <algorithm> 6 #include <cstring> 7 using namespace std; 8 typedef long long ll; 9 ll b[50005]; 10 ll a[50005]; 11 ll n; 12 void solve() 13 { 14 memset(b,0,sizeof(b)); 15 b[0]=a[0]; 16 int sum=1; 17 for(int i=1;i<n;i++)//枚举a数组 18 { 19 int pos=lower_bound(b,b+sum,a[i])-b;//lower_bound()返回值为b数组中有几个比a[i]小的 20 b[pos]=a[i]; //或者理解为用a[i]去更新b序列应更新的位置 21 sum=max(sum,pos+1);//长度更新 22 } 23 cout<<sum<<endl; 24 } 25 int main() 26 { 27 cin>>n; 28 for(int i=0;i<n;i++) 29 cin>>a[i]; 30 solve(); 31 return 0; 32 }
51nod 1134 最长递增子序列 (O(nlogn)算法)
标签:lower 超时 src splay 复杂度 logs close 基础题 pen
原文地址:http://www.cnblogs.com/onlyli/p/7242906.html