Contest100000627 - 《算法笔记》11.3小节——动态规划专题->最长不下降子序列(LIS)

题目链接

A 最长上升子序列

  1. 最长不下降子序列(Longest Increasing Sequence,LIS):在一个数字序列中,找到一个最长的子序列(可以不连续),使得这个子序列是不下降的(非递减)的。这也是动态规划的经典题目。
  2. 穷举法的时间复杂度为 O\left ( 2^{n} \right ),使用动态规划可以降低至 O\left ( n^{2} \right )
  3. 令 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 的最大长度。
  4. 本题的参考代码如下。
#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;
}

猜你喜欢

转载自blog.csdn.net/weixin_42717165/article/details/87894040