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,得:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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 }
解法三:更快解法
维护一个数组,第一个元素储存长度为1的递增序列最小值,第二个元素储存长度为2的递增序列终点的最小值。。。数组长度即为最长。
做法:
每次插入,替换恰大于插入数的数,如果没有,否则直接插在后面。
如例子:
1
1 7
1 3
1 3 5
1 3 5 9
1 3 4 9
1 3 4 8
以上为每次插入后,数组的变化。注意,最后数组并不是最长递增子序列!
由于每次使用二分查找插入,所以时间复杂度是nlogn。
【本文章出自博客园willaty,转载请注明作者出处,误差欢迎指出~】