【洛谷习题】最长上升子序列
题目链接:https://www.luogu.org/problemnew/show/P1439
不要被题目名称骗到,虽然只是道模板题,然而LCS的模板只能得50分,1e5的数据范围会超时。
所以,其实考察的是LIS,嗯,因为是两个全排列,所以我们可以强制将序列1的数字顺序定义为上升序,序列2跟着改变,问题就转化为求序列2的最长上升子序列,就可以用O(nlogn)的做法了。
1 #include <cstdio> 2 #include <algorithm> 3 4 using namespace std; 5 6 inline int get_num() { 7 int num = 0; 8 char c = getchar(); 9 while (c < '0' || c > '9') c = getchar(); 10 while (c >= '0' && c <= '9') 11 num = num * 10 + c - '0', c = getchar(); 12 return num; 13 } 14 15 const int maxn = 1e5 + 5; 16 17 int lis[maxn], a1[maxn], a2[maxn]; 18 19 int main() { 20 int n, len = 0; 21 n = get_num(); 22 for (int i = 1; i <= n; ++i) a1[get_num()] = i; 23 for (int i = 1; i <= n; ++i) a2[i] = a1[get_num()]; 24 for (int i = 1; i <= n; ++i) { 25 if (a2[i] > lis[len]) lis[++len] = a2[i]; 26 else { 27 int pos = lower_bound(lis + 1, lis + len + 1, a2[i]) - lis; 28 lis[pos] = a2[i]; 29 } 30 } 31 printf("%d", len); 32 return 0; 33 }