NYOJ 760 - See LCS again(LCS转LIS)

来源:互联网 发布:java线程并发实例 编辑:程序博客网 时间:2024/04/28 05:21

题目链接 NYOJ760

【题意】

求最大公共子序列(LCS)

【分析】

直接求LCS,n^2超时,所以要优化,因为序列中每个元素不重复,所以直接用个数字保存第一个序列每个元素的下标,然后只要记录第二个序列中每个元素在第一个序列中的下标,如果在第一个序列中没出现直接不用记录,这样就有一个由第一个序列和第二个序列共同元素组成的下标的一个新序列,然后对于原来两个序列的LCS其实就是这个新序列的LIS了。

【AC代码】16ms

#include <cstdio>#include <cstring>#define MAXN 100010int ans, ch, s[MAXN], vis[MAXN];//vis[]保存a[]中各个元素的下标,s[]保存a[]b[]共同元素在a[]中下标,按照b[]出现的顺序int in(){while((ch = getchar())< '0' || '9' < ch);ans = ch-'0';while((ch = getchar()) >= '0' && '9' >= ch) ans = ans*10+ch-'0';return ans;}int main(){#ifdef SHYfreopen("e:\\1.txt","r",stdin);#endifint n,m;while(~scanf("%d %d%*c", &n, &m)){int len = 0, b, ans = 0;memset(vis,-1,sizeof(vis));for (int i = 0; i < n; i++)vis[in()] = i;for (int i = 0; i < m; i++){if (~vis[b=in()])s[len++] = vis[b];}vis[0] = 0;for (int i = 0; i < len; i++){if (s[i] > vis[ans])vis[++ans] = s[i];else{int l = 1, r = ans, mid;while(l <= r){mid = (l+r)>>1;if (vis[mid] >= s[i])r = mid-1;elsel = mid+1;}vis[l] = s[i];}}printf("%d\n", ans+1);}return 0;}


 

0 0
原创粉丝点击