返回
不简单的递增子序列:逐层攻破动态规划的经典习题
后端
2024-02-09 09:34:25
题目
给定一个长度为n的整数数组nums,求出其中最长的递增子序列的长度。
题目整理
- 输入:一个长度为n的整数数组nums。
- 输出:其中最长的递增子序列的长度。
解题思路
最长递增子序列问题是一个典型的动态规划问题。我们可以通过建立一个子问题状态表,将大问题分解成若干个相互关联的小问题,然后根据子问题的解来求得整个问题的解。
子问题状态表中每个单元格dp[i]表示以下标i结尾的最长递增子序列的长度。那么,dp[i]可以由如下递推公式求得:
dp[i] = max(dp[j] + 1)
其中,j < i且nums[j] < nums[i]。
具体实现
// 动态规划算法求最长递增子序列的长度
int longest_increasing_subsequence(vector<int>& nums) {
// 创建子问题状态表
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);
}
}
}
// 返回最终的解
return *max_element(dp.begin(), dp.end());
}
代码示例
#include <iostream>
#include <vector>
using namespace std;
int longest_increasing_subsequence(vector<int>& nums) {
// 创建子问题状态表
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);
}
}
}
// 返回最终的解
return *max_element(dp.begin(), dp.end());
}
int main() {
vector<int> nums = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
int length = longest_increasing_subsequence(nums);
cout << "最长递增子序列的长度为:" << length << endl;
return 0;
}
输出结果:
最长递增子序列的长度为:10
总结
最长递增子序列问题是一个典型的动态规划问题。通过建立子问题状态表,我们可以将大问题分解成若干个相互关联的小问题,然后根据子问题的解来求得整个问题的解。在本文中,我们详细介绍了如何使用动态规划算法来解决最长递增子序列问题,并给出了具体的实现和代码示例。