LIS 模型及其衍生:回头看,全是风景
一、前言:从 O(N) 到 O(N²)
和子数组(必须连续)不同,子序列允许跳跃选择。核心在于状态定义:dp[i] 通常表示以 i 位置结尾的最长子序列长度。由于不连续性,i 往往需要遍历 0 到 i-1 寻找最优前驱 j,这通常意味着双层循环。若规律涉及两个数(如等差、斐波那契),则需升维至二维 DP dp[i][j]。
二、最长递增子序列 (Medium)
题目描述
找到最长严格递增子序列的长度。
输入:[10,9,2,5,3,7,101,18]
输出:4 ([2,3,7,101])
核心思路
- 状态:
dp[i]表示以nums[i]结尾的最长递增子序列长度。 - 转移:站在
i位置往回看所有j(0 <= j < i)。如果nums[j] < nums[i],说明能接在j后面,选一个最长的dp[j]接上去。 - 公式:
dp[i] = max(dp[j] + 1)。
class Solution {
public:
int lengthOfLIS(vector<int>& nums) {
int n = nums.size();
if (n == 0) return 0;
vector<int> dp(n, 1);
int ret = 1;
for (int i = 1; i < n; i++) {
for (int j = 0; j < i; j++) {
if (nums[j] < nums[i]) {
dp[i] = max(dp[i], dp[j] + );
}
}
ret = (ret, dp[i]);
}
ret;
}
};


