最长公共子序列
Problem 11313 : No special judgement |
Problem description |
一个数列S,如果分别是两个已知数列的子序列,且是所有符合此条件序列中最长的,则 S 称为这二个序列的最长公共子序列。 Seat26最近很无聊,就去研究最长公共子序列,不过他发现这个问题已经被许多人解决了,没有什么好研究的,他想,要是给定的二个序列没有重复的元素会不会有更好的解法呢? |
Input |
输入有多组数据,每组数据包括三行,第一行有个正整数N,(1<=N<=100000,) 第二,三行有N个数,分别表示第一个数列和第二个数列,每个数列均是1到N的一个排列,最后一行是0,表示输入结束且不需要处理。 最后一行是0,表示输入结束且不需要处理。 |
Output |
对于每一组数据,输出S的长度. |
Sample Input |
3 3 2 1 2 1 3 4 2 1 3 4 3 2 4 1 0 |
Sample Output |
2 2 |
Problem Source |
湖南师范大学第四届大学生计算机程序设计竞赛 |
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
//代码来自队友 #include<stdio.h> #include<string.h> #define MAX 100005 //求排列date与b的最长公共子序列 int date[MAX],a[MAX],b[MAX],f[MAX]; int main() { int n,i,j,m,max; while(scanf("%d",&n),n) { for(i=0; i<n; i++) scanf("%d",date+i); for(i=0; i<n; i++) { scanf("%d",&m); b[m]=i; }//把b数组压缩,形成date有序 for(i=0; i<n; i++) a[b[date[i]]+1]=i+1; a[0]=0; max=0; memset(f,127,sizeof(f)); f[0]=0; for(i=1; i<=n; i++) //求最长递增子序列 { for(j=max; f[j]>=a[i]&&j>=0; j--); if(a[i]<f[j+1]) f[j+1]=a[i]; if(j+1>max) max=j+1; } printf("%d\n",max); } return 0; }