标签:ase pre number cond iostream ring common elements 数据
/* See LCS again
时间限制:1000 ms | 内存限制:65535 KB
难度:3
描述
There are A, B two sequences, the number of elements in the sequence is n、m;
Each element in the sequence are different and less than 100000.
Calculate the length of the longest common subsequence of A and B.
输入
The input has multicases.Each test case consists of three lines;
The first line consist two integers n, m (1 < = n, m < = 100000);
The second line with n integers, expressed sequence A;
The third line with m integers, expressed sequence B;
输出
For each set of test cases, output the length of the longest common subsequence of A and B, in a single line.
样例输入
5 4
1 2 6 5 4
1 3 5 4
样例输出
3
*/
//题意是要求公共子序列的长度,并且保证输入串中每串数字中没有重复的数字;
//由于题目给的数据要求太大,故用一般的二维数组dp内存就超了,所以借鉴了一个大牛的技巧,将问题转化为求最长上
//升子序列。
#include <iostream>
#include <cstring>
#include <cstdio>
using namespace std;
int a[100005];
int b[100005];
int find(int *c, int low, int high, int x){
while(low < high){
int mid = (low + high) / 2;
if(x < c[mid]){
high = mid;
}
else{
low = mid + 1;
}
}
return low;
}
int main(){
int n, m;
while(~scanf("%d%d", &n, &m)){
memset(a, 0, sizeof(a));
memset(b, 0, sizeof(b));
int x = 0;
for(int i = 1; i <= n; i++){
scanf("%d", &x);
a[x] = i; //将第一串数字,标记在a数组中,将对应位置存为对应数字出现的序号
}
int y = 0, j = 0;
for(int i = 1; i <= m; i++){
scanf("%d", &y);
if(a[y]){ //看该数字是否在第一串数字中出现
b[j++] = a[y]; //将公共数字出现的序号存下来,所以后面最长上升子序列就是两串数字的公共子序列个数
}
}
//求b的上升子序列:
int len = 0, c[10005]={b[0]};
for(int i = 1; i < j; i++){
if(b[i] > c[len]){
c[++len] = b[i];
}
else{
int w = find(c, 0, len, b[i]);
c[w] = b[i];
}
}
printf("%d\n", len + 1);
}
return 0;
}
标签:ase pre number cond iostream ring common elements 数据
原文地址:http://www.cnblogs.com/zhumengdexiaobai/p/7429652.html