DP经典 之 CODE[VS] 1576 最长严格上升子序列 (O(n^2) 和 O(nlogn))

O(n^2):

 1 /*
 2 
 3 最长严格上升子序列
 4 dp[i] : 以第i个整数结尾的最长严格上升子序列长度
 5 dp[i] = max(dp[x]) + 1
 6 注: x < i && arr[x] < arr[i]
 7 
 8 */
 9 
10 #define _CRT_SECURE_NO_WARNINGS
11 #include <iostream>
12 #include <cstdio>
13 #include <cstdlib>
14 #include <cmath>
15 #include <string>
16 #include <algorithm>
17 #include <cstring>
18 #include <set>
19 #include <utility>
20 #include <locale>
21 #include <ctime>
22 using namespace std;
23 //using int64 = long long;
24 const int INF = 0x3f3f3f3f;
25 const int MaxN = 5010;
26 
27 int arr[MaxN];
28 int dp[MaxN];
29 
30 void Solve()
31 {
32 }
33 
34 int main()
35 {
36 
37     int len = 0;
38     cin >> len;
39     for (int i = 0; i < len; ++i) cin >> arr[i];
40     fill(dp, dp + len, 1);
41     for (int i = 0; i < len; ++i)
42     {
43         for (int j = 0; j < i; ++j)
44         {
45             if (arr[j] < arr[i]) dp[i] = max(dp[i], dp[j] + 1);
46         }
47     }
48     cout << *max_element(dp, dp + len) << endl;
49 
50 
51 #ifdef HOME
52     cerr << "Time elapsed: " << clock() / CLOCKS_PER_SEC << " ms" << endl;
53 #endif
54     return 0;
55 }

O(nlogn):

 1 /*
 2 最长严格上升子序列 O(nlogn)
 3 dp[i] : 长度为i+1的上升子序列中末尾元素的最小值(不存在的话,就是INF)
 4 */
 5 
 6 #include <iostream>
 7 #include <cstdio>
 8 #include <cstdlib>
 9 #include <cmath>
10 #include <string>
11 #include <algorithm>
12 #include <cstring>
13 #include <set>
14 #include <utility>
15 #include <locale>
16 #include <limits>
17 #include <ctime>
18 using namespace std;
19 //using int64 = long long;
20 const int INF = numeric_limits<int>::max();
21 const int MaxN = 5010;
22 
23 int N, arr[MaxN];
24 int dp[MaxN];
25 
26 void Solve()
27 {
28     fill(dp, dp + N, INF);
29     for (int i = 0; i < N; ++i)
30     {
31         *lower_bound(dp, dp + N, arr[i]) = arr[i];
32     }
33     cout << lower_bound(dp, dp + N, INF) - dp << endl;
34 }
35 
36 int main()
37 {
38     
39     cin >> N;
40     for (int i = 0; i < N; ++i) cin >> arr[i];
41     Solve();
42 
43 #ifdef HOME
44     cerr << "Time elapsed: " << clock() / CLOCKS_PER_SEC << " ms" << endl;
45 #endif
46     return 0;
47 }

注:

(1)lower_bound(arr, arr + len, k):二分搜索,返回指向满足arr[i]>=k的最小指针。

       详细参考这里:点击

       实例参考这里:点击

(2)求int类型最大值:const int INF = numeric_limits<int>::max()。 详细参考这里:点击

 不可以设为0x3f3f3f3f,因为测试数据整数值已经超过ox3f3f3f3f:

0x3f3f3f3f化为10进制:1061109567

测试数据:

原文地址:https://www.cnblogs.com/shijianming/p/4847728.html