📅  最后修改于: 2023-12-03 15:26:28.880000             🧑  作者: Mango
最长递增子序列(Longest Increasing Subsequence,简称 LIS)问题是指给定一个无序的序列,求出这个序列中最长的严格递增子序列的长度。这个问题在计算机科学、通信网络、自动控制等领域都有着广泛的应用。
以下是用 C++ 实现 LIS 问题的程序。
该程序采用动态规划思想,用一个数组 dp 存储以每个元素为结尾的最长递增子序列长度。然后遍历整个序列,每遇到一个数就求出以该数为结尾的最长递增子序列的长度,并更新 dp 数组。最后,dp 数组中的最大值就是该序列的最长递增子序列长度。
#include <iostream>
#include <vector>
using namespace std;
int LIS(vector<int>& nums) {
if (nums.empty()) {
return 0;
}
vector<int> dp(nums.size(), 1);
for (int i = 1; i < nums.size(); ++i) {
for (int j = 0; j < i; ++j) {
if (nums[j] < nums[i]) {
dp[i] = max(dp[i], dp[j] + 1);
}
}
}
int maxLen = 1;
for (int i = 0; i < dp.size(); ++i) {
maxLen = max(maxLen, dp[i]);
}
return maxLen;
}
int main() {
vector<int> nums = {10, 9, 2, 5, 3, 7, 101, 18};
int len = LIS(nums);
cout << "The length of the longest increasing subsequence is " << len << endl;
return 0;
}
该程序首先定义了一个 LIS 函数,函数的参数是一个整数型数组 nums。在函数中,首先判断 nums 是否为空,如果为空,则直接返回 0。否则,定义一个存储以每个元素为结尾的最长递增子序列长度的数组 dp,并初始化为 1。
接下来,使用双重循环遍历整个数组,当遇到 nums[j] < nums[i] 满足递增子序列要求时,更新 dp[i]。最后,在 dp 数组中查找最大值,返回该值即为该序列的最长递增子序列长度。
主函数中,定义了一个整数型数组 nums,示例值为 {10, 9, 2, 5, 3, 7, 101, 18}。调用 LIS 函数并输出结果。
这段程序的时间复杂度为 O(n^2),虽然没有最优解的 O(nlogn) 快,但是已经足够应对一般情况。
代码片段中的关键语句:
vector<int> dp(nums.size(), 1);
for (int i = 1; i < nums.size(); ++i) {
for (int j = 0; j < i; ++j) {
if (nums[j] < nums[i]) {
dp[i] = max(dp[i], dp[j] + 1);
}
}
}
int maxLen = 1;
for (int i = 0; i < dp.size(); ++i) {
maxLen = max(maxLen, dp[i]);
}
本篇文章介绍了最长递增子序列问题以及采用动态规划思想解决该问题的 C++ 程序。该程序算法简单,代码清晰易懂,适合初学者学习。