LIS(nlogn) POJ 3903 Stock Exchange

 

题目传送门

 1 /*  2  最长递增子序列O(nlogn)算法:  3  设当前最长递增子序列为len,考虑元素a[i];  4  若d[len]<a[i],则len++,并将d[len]=a[i];  5  否则,在d[1~len]中二分查找,找到第一个比它小的元素d[j],并d[j]=a[i]。  6 */  7 #include <cstdio>  8 #include <cstring>  9 #include <iostream> 10 #include <algorithm> 11 #include <cmath> 12 #include <vector> 13 using namespace std; 14 15 const int MAX_N = 100000 + 10; 16 const int INF = 999999999; 17 int a[MAX_N]; 18 int d[MAX_N]; 19 int n, m; 20 21 int BinSearch(int key, int low, int high) 22 { 23 while(low <= high) 24  { 25 int mid = low + (high - low) / 2; 26 if(key > d[mid]) 27 low = mid + 1; 28 else 29 high = mid - 1; 30  } 31 return low; 32 } 33 34 int LIS(void) //O(nlogn) 二分查找优化 35 { 36 int len = 1; 37 int j; 38 d[1] = a[1]; 39 40 for (int i=2; i<=n; ++i) 41  { 42 if (d[len] < a[i]) 43 d[++len] = a[i]; 44 else 45  { 46 j = BinSearch (a[i], 1, len); 47 d[j] = a[i]; 48  } 49  } 50 return len; 51 } 52 53 int main(void) //POJ 3903 Stock Exchange(LIS) 54 { 55 //freopen ("inE.txt", "r", stdin); 56 57 while (scanf ("%d", &n) != EOF) 58  { 59 for (int i=1; i<=n; ++i) 60  { 61 scanf ("%d", &a[i]); 62  } 63 64 printf ("%d\n", LIS ()); 65  } 66 67 return 0; 68 } 69 70 71 /* 72  int res = 0; 73  for (int i=1; i<=n; ++i) //O(n^2) 超时 74  { 75  dp[i] = 1; 76  for (int j=1; j<i; ++j) 77  { 78  if (a[i] < a[j] + 1) 79  { 80  dp[i] = dp[j] + 1; 81  } 82  } 83  res = max (res, dp[i]); 84  } 85 */

 

你可能感兴趣的:(Exchange)