文章目录
0. 前言
相关:
1. LIS 变种模型
重点: 线性 dp
、LIS 问题
思路:
- 先严格上升、再严格下降。则正向求一遍
LIS
、反向再求一遍LIS
,两者相加再减去重复点 1 即可 - 区别与 [线性dp] 怪盗基德的滑翔翼(最长上升子序列模型) 的是,怪盗基德是在某个位置上单向的
LIS
求解,其正反求完取MAX
,而本题是在某个位置上双向的LIS
求解,其正反求完再求和 - 时间复杂度: O ( n 2 ) O(n^2) O(n2)
正反两遍再求和代码:
#include <iostream>
#include <algorithm>
using namespace std;
const int N = 1005;
int n;
int a[N];
int f[N], d[N];
int main() {
cin >> n;
for (int i = 0; i < n; ++i) cin >> a[i];
for (int i = 0; i < n; ++i) {
f[i] = d[i] = 1;
for (int j = 0; j < i; ++j)
if (a[i] > a[j])
f[i] = max(f[i], f[j] + 1);
}
for (int i = n - 1; i >= 0; --i) {
d[i] = 1;
for (int j = n - 1; j >= i; --j)
if (a[i] > a[j])
d[i] = max(d[i], d[j] + 1);
}
int res = 0;
for (int i = 0; i < n; ++i) res = max(res, f[i] + d[i] - 1);
cout << res << endl;
return 0;
}