伊娃(Eva)试图用给定的颜色制作自己的彩色条纹。她想通过剪下那些多余的部分并将其余部分缝合在一起以形成她喜欢的色带,从而按自己喜欢的顺序只保留她喜欢的颜色。
据说正常的人只能分辨不到 200 种不同的颜色,因此 Eva 最喜欢的颜色是有限的。但是,原始的条带可能会很长,Eva 希望保留她最喜欢的颜色,并使其长度最大。
请注意,解决方案可能不是唯一的,但您只需要告诉她最大长度即可。例如,给定颜色为{2 2 4 1 5 5 6 3 1 1 5 6}的条纹。如果 Eva 最喜欢的颜色以她喜欢的顺序给出,例如{2 3 1 5 6},则她有 4 种可能的最佳解决方案:{2 2 1 1 1 5 6},{2 2 1 5 5 5 6},{2 2 1 5 5 6 6}和{2 2 3 1 1 5 6}。
输入第一行都包含一个正整数 N,它是所涉及颜色的总数(因此,颜色从 1 到 N 编号)。然后,下一行以一个正整数 M 开始,然后是 M 个按 Eva 喜欢的顺序给出的她喜欢的颜色数字。最后第三行以正整数 L 开始,L 是给定条纹的长度,然后是条纹上的 L 种颜色。一行中的所有数字均以空格隔开。
只需在一行中打印 Eva 最喜欢的条纹的最大长度即可。
你需要了解最长不下降子序列
的动态规划解法。
#include <bits/stdc++.h>
using namespace std;
using gg = long long;
int main() {
ios::sync_with_stdio(false);
cin.tie(0);
gg ni, mi, li, ai;
cin >> ni >> mi;
unordered_map<gg, gg> order;
for (gg i = 0; i < mi; ++i) {
cin >> ai;
order[ai] = i;
}
cin >> li;
vector<gg> v;
while (li--) {
cin >> ai;
if (order.count(ai)) {
v.push_back(order[ai]);
}
}
vector<gg> dp(v.size(), INT_MAX);
for (gg i : v) {
*upper_bound(dp.begin(), dp.begin() + v.size(), i) = i;
}
cout << lower_bound(dp.begin(), dp.begin() + v.size(), INT_MAX) - dp.begin();
return 0;
}