luogu1439 【模板】最长公共子序列
题目描述
给出1-n的两个排列P1和P2,求它们的最长公共子序列。
输入输出格式
输入格式: 第一行是一个数n,
接下来两行,每行为n个数,为自然数1-n的一个排列。
输出格式: 一个数,即最长公共子序列的长度
输入输出样例
输入样例#1: 复制
5 3 2 1 4 5 1 2 3 4 5 输出样例#1: 复制
3 说明
【数据规模】
对于50%的数据,n≤1000
对于100%的数据,n≤100000
这题要求lcs乍一看 这个n太大了 没法做 但是题目中给的是一个n的排列 那么我们可以根据a中的位置对b进行重排列 然后求一个最长上升子序列即可 用二分查找 动态规划的方法找 时间复杂度n log(n)
#include#include#includeusing namespace std;#define inf 0x7f7f7f7f#define N 110000inline char gc(){ static char now[1<<16],*S,*T; if (T==S){T=(S=now)+fread(now,1,1<<16,stdin);if (T==S) return EOF;} return *S++;}inline int read(){ int x=0;char ch=gc(); while (ch<'0'||ch>'9') ch=gc(); while (ch<='9'&&ch>='0'){x=x*10+ch-'0';ch=gc();} return x;}int n,a[N],b[N],c[N];int main(){// freopen("1439.in","r",stdin); n=read(); for (int i=1;i<=n;++i) a[i]=read(),b[a[i]]=i; for (int i=1;i<=n;++i){int tmp=0;tmp=read();c[i]=b[tmp];} memset(b,0x7f,sizeof(b));b[1]=c[1]; for (int i=2;i<=n;++i){ int len=upper_bound(b+1,b+n+1,c[i])-b-1; b[len+1]=c[i]; }int ans=1; //for (int i=1;i<=n;++i) printf("%d,b[i]);printf("\n"); for (int i=1;i<=n;++i) if (b[i]==inf) break;else ans=i; printf("%d",ans); return 0;}
版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。
暂时没有评论,来抢沙发吧~