【1045 30 LIS】 Favorite Color Stripe
传送门
题意
给定所有数的个数 \(cnt\),给定长度为 \(n\) 的序列 \(a\),长度为 \(m\) 的序列 \(b\),求出 \(b\) 序列中所有出现在 \(a\) 序列中的元素中按照 \(a\) 序列下标大小的最长不下降子序列
数据范围
\(cnt\leq 200\)
\(n\leq 200\)
\(m\leq 10^{4}\)
题解
- 即求按照对应
order序列下标大小的最长不下降子序列长度 - \(n^2\) 和 \(nlogn\) 都可以
Code
$n^2$ 做法
#include <bits/stdc++.h>
using namespace std;
int main() {
int n, m; cin >> n >> m;
unordered_map<int, int> idx;
for (int i = 1; i <= m; i++) {
int x; cin >> x;
idx[x] = i;
}
int L; cin >> L;
vector<int> seq(L), dp(L);
for (int i = 0; i < L; i++) {
int x; cin >> x;
seq[i] = idx[x];
}
for (int i = 0; i < L; i++) {
dp[i] = 1;
for (int j = 0; j < i; j++) {
if (seq[i] >= seq[j]) {
dp[i] = max(dp[i], dp[j] + 1);
}
}
}
cout << dp[L - 1] << endl;
}
$nlogn$ 做法
#include <bits/stdc++.h>
using namespace std;
int main() {
int n, m; cin >> n >> m;
unordered_map<int, int> idx;
for (int i = 1; i <= m; i++) {
int x; cin >> x;
idx[x] = i;
}
int L; cin >> L;
vector<int> seq, dp(L + 1);
for (int i = 0; i < L; i++) {
int x; cin >> x;
if (idx[x]) seq.push_back(idx[x]);
}
int length = 0;
dp[0] = -1e9;
for (int i = 0; i < seq.size(); i++) {
int l = 0, r = length;
while (l < r) {
int mid = l + r + 1 >> 1;
if (dp[mid] <= seq[i]) {
l = mid;
} else {
r = mid - 1;
}
}
length = max(length, r + 1);
dp[r + 1] = seq[i];
}
cout << length << endl;
}

浙公网安备 33010602011771号