文章目录
0. 前言
相关:
1. LIS 变种模型
重点: 线性 dp
、LIS 问题
思路:
- 理解题目后就是个正向、反向的
LIS
- 也可理解为最长上升,最长下降子序列都行
在此不讨论 O ( n l o g n ) O(nlogn) O(nlogn) 做法。[线性dp] 最长上升子序列(模板题+最长上升子序列模型) 自行学习~
正反两遍 LIS做法代码:
// 以后,表示次数,多组循环输入这个参数,一定不要用n....
#include <iostream>
#include <algorithm>
using namespace std;
const int N = 105;
int n;
int a[N];
int f[N];
int main() {
cin >> n;
while (n --) {
int m;
cin >> m;
for (int i = 0; i < m; ++i) cin >> a[i];
// 正向LIS
int res = 0;
for (int i = 0; i < m; ++i) {
f[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 = 0; i < m; ++i) res = max(res, f[i]);
// 反向LIS
for (int i = m - 1; i >= 0; --i) {
f[i] = 1;
for (int j = m - 1; j >= i; --j) {
if (a[i] > a[j])
f[i] = max(f[i], f[j] + 1);
}
}
for (int i = 0; i < m; ++i) res = max(res, f[i]);
cout << res << endl;
}
return 0;
}
最长上升、下降做法代码:
#include <iostream>
#include <algorithm>
using namespace std;
const int N = 105;
int n;
int a[N];
int f[N], d[N];
int main() {
int T;
cin >> T;
while (T --) {
cin >> n;
for (int i = 0; i < n; ++i) cin >> a[i];
int res = 0, ser = 0;
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);
else if (a[i] < a[j]) d[i] = max(d[i], d[j] + 1);
res = max(res, f[i]);
ser = max(ser, d[i]);
}
cout << max(res, ser) << endl;
}
return 0;
}