概念
最长上升子序列,注意其元素在原序列中不一定是连续的。
解决该问题的算法要求在
n
l
o
g
(
n
)
nlog(n)
nlog(n)以内。
相关算法
解决该问题与最长公共子序列问题密切相关。
例如序列S,其排序后的序列为T,则S的最长递增子序列是S和T最长公共子序列。
算法
使用数组和二分查找算法。
核心是确定dp[i]表示的意思,以及更新。
例如:
5
0 1 0 3 2
解法
// 找出最长上升子序列,数组+dp
// 确定好dp[i]表示什么, 表示前i的序列的最长上升子序列的长度
// 求得递推式,dp[i] = max(dp[i], dp[j]+1),这里的dp[j]应该满足num[i] > num[j]的
#include <bits/stdc++.h>
using namespace std;
vector<int> nums;
int main()
{
int n; cin >> n;
for (int i = 1; i <= n; i++){
int x; cin >> x;
nums.push_back(x);
}
// dp思想
vector<int> dp(nums.size(), 1); // 初始值为1,即自己本身
int res = 0;
for (int i = 1; i < nums.size(); i++){
for (int j = 0; j < i; j++){
if (nums[i] > nums[j]) dp[i] = max(dp[i], dp[j]+1);
}
// 每一次i的位置更新后更新最长子序列长度
if (dp[i] > res) res = dp[i];
}
cout << res;
return 0;
}
参考:
https://zh.wikipedia.org/wiki/%E6%9C%80%E9%95%BF%E9%80%92%E5%A2%9E%E5%AD%90%E5%BA%8F%E5%88%97