【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;
}
posted @ 2021-02-23 02:15  Hyx'  阅读(59)  评论(0)    收藏  举报