NYOJ 760 - See LCS again(LCS转LIS)
2014-07-08 22:03
357 查看
题目链接
NYOJ760
【题意】
求最大公共子序列(LCS)
【分析】
直接求LCS,n^2超时,所以要优化,因为序列中每个元素不重复,所以直接用个数字保存第一个序列每个元素的下标,然后只要记录第二个序列中每个元素在第一个序列中的下标,如果在第一个序列中没出现直接不用记录,这样就有一个由第一个序列和第二个序列共同元素组成的下标的一个新序列,然后对于原来两个序列的LCS其实就是这个新序列的LIS了。
【AC代码】16ms
NYOJ760
【题意】
求最大公共子序列(LCS)
【分析】
直接求LCS,n^2超时,所以要优化,因为序列中每个元素不重复,所以直接用个数字保存第一个序列每个元素的下标,然后只要记录第二个序列中每个元素在第一个序列中的下标,如果在第一个序列中没出现直接不用记录,这样就有一个由第一个序列和第二个序列共同元素组成的下标的一个新序列,然后对于原来两个序列的LCS其实就是这个新序列的LIS了。
【AC代码】16ms
#include <cstdio> #include <cstring> #define MAXN 100010 int 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 SHY freopen("e:\\1.txt","r",stdin); #endif int 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; else l = mid+1; } vis[l] = s[i]; } } printf("%d\n", ans+1); } return 0; }
相关文章推荐
- NYOJ 题目760 See LCS again(LIS求LCS)
- NYOJ 760 See LCS again
- nyoj 760 See LCS again
- NYOJ760-See LCS again,有技巧的暴力!
- Nyoj 760 See LCS again [Lcs]
- NYOJ - 760 - See LCS again(最长上升子序列O(N(logN)实现)
- NYOJ 760 See LCS again(基础dp+哈希表)(复习)
- NYIST 760 See LCS again
- See LCS again
- SeeLCSagain
- ayit See LCS again
- nyistOJ-See LCS again(二分)
- See LCS again 最长递增子序列到最长公共子序列的转化
- See LCS again
- See LCS again
- NYOJ760又见LCS
- See LCS again
- See LCS again
- NYOJ 17(LIS转为LCS,但是MLE)
- 【算法】旋转数组最小值、零子数组、LCS、LIS、字符串编辑距离