题目大意:
求两个序列的最长子序列
代码:
#include<cstdio>
#include<algorithm>
#include<string>
#include<cstring>
using namespace std;
int n, p, q;
const int maxn = 250*250;
int num1[maxn];
int hash[maxn], stack[maxn];
int main() {
int kase;
scanf("%d", &kase);
for(int y=1; y<=kase; y++) {
scanf("%d%d%d", &n, &p, &q);
p++, q++;
memset(num1, 0, sizeof(num1));
int x;
for(int i=1; i<=p; i++) {
scanf("%d", &x);
num1[x] = i;
}
int top=0;
stack[0] = -1;
for(int i=1; i<=q; i++) {
scanf("%d", &x);
x = num1[x];
if(x) {
if(x > stack[top]) stack[++top]=x;
else {//这里一开始想的很简单,觉得只要与倒二个比较,若比待插入的数字小,则替换最后一个数字,后来发现不行,还是要找到第一个比他大的位置替换.
int l=1, r=top;
while(l<=r) {
int mid = (l+r)/2;
if(stack[mid]<x) l=mid+1;
else r=mid-1;
}
stack[l] = x;
}
}
}
printf("Case %d: %d\n", y, top);
}
return 0;
}
思路:一开始看题目觉得好水,用二位数组做,后来发现dp[250*250][250*250]是不行的,看了某博主的做法,只需一维数组.
用一个一维数组记录第一行输入数据(下标为值,存储位置),输入第二组时,只有在判断输入的数出现在了第一组才进行相应操作,即用一个数组存储有序序列,最后数组下标即为长度.