POJ2533 最长递增子序列

描述:

7

1 7 3 5 9 4 8

输出4

最长递增子序列为1 3 5 9,不必连续。

 

解法:

三种思路:

转化为最长公共子序列(n^2),动态规划(n^2),不知叫什么解法(nlogn)。

解法一:转化

先排序nlogn,在最长公共子序列

解法二:动态规划

dp[i]定义为,以此数为终点的最长递增子序列,

则dp[i] = dp[j] + 1,且dp <- max(dp[0] .. dp[i - 1]), a[i] > a[j]

注意处理边界条件,如果不存在dp[i],则赋值为1,得:

 1 #include <iostream>
 2 using namespace std;
 3 
 4 int main()
 5 {
 6     int n;
 7     cin >> n;
 8     int* arr = new int[n]();
 9     int* arr_data = new int[n]();
10 
11     for (int i = 0; i < n; ++i) {
12         int more;
13         cin >> more;
14         arr_data[i] = more;
15         if (i == 0) {
16             arr[0] = 1;
17             continue;
18         }
19 
20         int big = 1;
21         for (int j = 0; j < i; ++j) {
22             if (arr_data[j] < more && big < arr[j] + 1)
23                 big = arr[j] + 1;
24         }
25         arr[i] = big;
26     }
27 
28     int ma = arr[0];
29     for (int i = 1; i < n; ++i)
30         if (ma < arr[i])
31             ma = arr[i];
32 
33     cout << ma << endl;
34     return 0;
35 }
View Code

解法三:更快解法

维护一个数组,第一个元素储存长度为1的递增序列最小值,第二个元素储存长度为2的递增序列终点的最小值。。。数组长度即为最长。

做法:

每次插入,替换恰大于插入数的数,如果没有,否则直接插在后面。

如例子:

1

1 7

1 3

1 3 5

1 3 5 9

1 3 4 9

1 3 4 8

以上为每次插入后,数组的变化。注意,最后数组并不是最长递增子序列!

由于每次使用二分查找插入,所以时间复杂度是nlogn。

posted on 2017-12-20 20:29  willaty  阅读(180)  评论(0编辑  收藏  举报

导航