一、LIS(最长上升子序列)
LIS也是dp的经典问题,学了上升序列,下降也是同一个道理了。
总之,我们需要一个数组存子序列长度。
c++代码:
int dp[MAX_N], a[MAX_N], n;
int ans = 0; // 保存最大值
for (int i = 1; i <= n; ++i) {
dp[i] = 1;
for (int j = 1; j < i; ++j) {
if (a[j] < a[i]) {
dp[i] = max(dp[i], dp[j] + 1);
}
}
ans = max(ans, dp[i]);
}
cout << ans << endl; // ans 就是最终结果
改进优化:
int ans[MAX_N], a[MAX_N], dp[MAX_N], n; // ans 用来保存每个 dp 值对应的最小值,a 是原数组
int len; // LIS 最大值
ans[1] = a[1];
len = 1;
for (int i = 2; i <= n; ++i) {
if (a[i] > ans[len]) {
ans[++len] = a[i];
} else {
int pos = lower_bound(ans, ans + len, a[i]) - ans;
ans[pos] = a[i];
}
}
cout << len << endl; // len 就是最终结果
对于lower_bound函数:大家可以看这里:
C++ lower_bound 与 upper_bound 函数
二、LCS(最长公共子序列)
关于原生例题:点这里!