题目链接:http://acm.nyist.net/JudgeOnline/problem.php?pid=760
思路: 如果按正常的思路,都开不下那么大的数组,并且时间是1S。 注意到题目说一个序列中的数两两不同,这样我们就可以把第一个数组出现在数字的下标都记下来,然后对照第二个数组 再生成一个下标数组,求这个生成的数组的最长单调递增子序列就可以了。
代码:
#include <cstdio>
#include <cstring>
using namespace std;
const int maxn = 1e5 + 5;
int f[maxn],g[maxn];
int s_(int key,int l,int r)
{
int m;
while(l <= r)
{
m = (l + r) / 2;
if(f[m] < key && key <= f[m + 1])
return m;
else if(f[m] < key)
l = m + 1;
else
r = m - 1;
}
return 0;
}
int main()
{
int n,m;
while(~scanf("%d%d",&n,&m))
{
memset(f,0,sizeof(f));
int x;
for(int i = 1;i <= n;++i)
{
scanf("%d",&x);
f[x] = i;
}
int j = 0;
for(int i = 1;i <= m;++i)
{
scanf("%d",&x);
if(f[x])
g[j++] = f[x];
}
int maxlen = 1;
f[1] = g[0];
for(int i = 1;i < j;++i)
{
if(g[i] > f[maxlen])
f[++maxlen] = g[i];
else
{
f[s_(g[i],1,maxlen) + 1] = g[i];
}
}
printf("%d\n",maxlen);
}
}