标签:
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 */
LIS(nlogn) POJ 3903 Stock Exchange
标签:
原文地址:http://www.cnblogs.com/Running-Time/p/4466966.html