题目链接
A 最长上升子序列
- 最长不下降子序列(Longest Increasing Sequence,LIS):在一个数字序列中,找到一个最长的子序列(可以不连续),使得这个子序列是不下降的(非递减)的。这也是动态规划的经典题目。
- 穷举法的时间复杂度为 ,使用动态规划可以降低至 。
- 令 dp[i] 表示以 N[i] 结尾的最长不下降子序列的长度(和最大连续子序列和问题一样,以 N[i] 结尾是强制要求)对于 dp[i] ,考虑 N[i] 之前的某个元素 N[j] (j < i) ① 如果有 N[j] <= N[i] ,那么就有一个 临时的 dp[i] = dp[j]+1。对于所有的 j < i,找到 dp[i] = dp[j]+1 中的最大值作为 dp[i] 的值;② 如果对于所有 j < i 都有 N[j] > N[i],那么 dp[i] = 1 。最后遍历 dp 数组,最大的值即为 LIS 的最大长度。
- 本题的参考代码如下。
#include<iostream>
#include<algorithm>
using namespace std;
const int MAXN = 1010;
int N[MAXN], dp[MAXN];
int main() {
int n;
cin >> n;
for (int i = 0; i < n; i++)
cin >> N[i];
for (int i = 0; i < n; i++) {
dp[i] = 1;
for (int j = 0; j < i; j++) {
if (N[j] <= N[i] && dp[j] + 1 > dp[i])
dp[i] = dp[j] + 1;
}
}
int index = 0;
for (int i = 0; i < n; i++)
if (dp[i] > dp[index])
index = i;
cout << dp[index] << endl;
return 0;
}