最长公共子序列转化最长上升子序列 n log n做法

匿名 (未验证) 提交于 2019-12-03 00:22:01

题目描述
给出1-n的两个排列P1和P2,求它们的最长公共子序列。
输入输出格式
输入格式:
第一行是一个数n,
接下来两行,每行为n个数,为自然数1-n的一个排列。
输出格式:
一个数,即最长公共子序列的长度

如题。
我们让id[i]为数字i在P1中出现的位置。
然后对于第二行出现的数字j,我们只需要知道它在第一行出现的位置,放在数组data里面,让data[i]=id[P2[j]],求最长上升子序列即可。
这个正确性我不会证明。。。但是举例子一看确乎可以。。

#include<bits/stdc++.h> using namespace std; inline int read(){     int num=0;char c=' ';bool flag=true;     for(;c>'9'||c<'0';c=getchar())         if(c=='-')             flag=false;     for(;c>='0'&&c<='9';num=(num<<3)+(num<<1)+c-48,c=getchar());     return flag ? num : -num; } const int maxn=100020; int id[maxn],data[maxn],n,a[maxn],b[maxn],t[maxn],top; int main(){     n=read();     for(int i=1;i<=n;i++){         a[i]=read();         id[a[i]]=i;     }     for(int i=1;i<=n;i++)         b[i]=read();     for(int i=1;i<=n;i++){         if(id[b[i]]>t[top]){             t[++top]=id[b[i]];             continue;         }         int k=lower_bound(t+1,t+top+1,id[b[i]])-t;         t[k]=id[b[i]];     }     printf("%d\n",top);     return 0; }
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!