线性动态规划核心模型实战
线性 DP 是算法竞赛和工程面试中的高频考点,其中最长上升子序列(LIS)与最长公共子序列(LCS)构成了大多数变体的基础。掌握这两类问题的状态定义与转移技巧,能解决合唱队形、编辑距离等复杂场景。
最长上升子序列 (LIS)
O(n²) 基础解法
当数据规模在几千以内时,使用标准的二维 DP 思路即可。
核心思路
dp[i] 表示以第 i 个元素结尾的最长上升子序列长度。对于每个位置 i,我们需要遍历它之前的所有位置 j,如果 a[j] < a[i],则尝试用 dp[j] + 1 更新 dp[i]。
参考实现
#include<iostream>
#include<algorithm>
using namespace std;
const int N = 5010;
int n;
int a[N], dp[N];
int main() {
cin >> n;
for(int i = 1; i <= n; i++) {
cin >> a[i];
}
int ret = 0;
// 按序填表
for(int i = 1; i <= n; i++) {
dp[i] = 1; // 初始化自身长度为 1
for(int j = 1; j < i; j++) {
if(a[j] < a[i]) {
dp[i] = max(dp[i], dp[j] + 1);
}
}
ret = max(ret, dp[i]);
}
cout << ret << endl;
return 0;
}


