哈理工1598-序列问题III
Description
有俩个长度分别为p和q的序列A和B,每个序列的各个元素互不相同,且每个元素的大小都是1~(p和q中的最大值)之间的正整数。
俩个序列的第一个元素都为1,求出A和B的最长公共子序列长度。
Input
输入第一行为数据组数T(T<=20)。每组数据包括3行,第一行为2个整数p和q(1<=p,q<=10000),
第二行包含序列A,其中第一个数为1。
第三行包含序列B,格式同序列A。
Output
对于每组数据,输出A和B的最长公共子序列的长度。
Sample Input
2
3 2
1 2 3
1 2
7 8
1 7 5 4 8 3 2
1 4 3 5 6 2 8 7
Sample Output
2
4
Hint
对于第二组数据最长公共子序列为1,4,3,2。
#include<stdio.h>
#include<string.h>
#include<map>
#include<algorithm>
using namespace std;
int a[1000800];
int f[1000800];
int Slove(int n)
{
int c=0;
for(int i=1; i<=n; i++)
{
int t=a[i];
if(i==1)
{
f[++c]=t;
}
else
{
if(t>f[c]) f[++c]=t;
else
{
int pos=lower_bound(f+1,f+c,t)-f;
f[pos]=t;
}
}
}
return c;
}
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
int n,m;
scanf("%d%d",&n,&m);
map<int,int >pos;
for(int i=1; i<=n; i++)
{
int x;
scanf("%d",&x);
pos[x]=i;
}
for(int i=1; i<=m; i++)
{
int x;
scanf("%d",&x);
if(pos[x]==0)a[i]=-1;
else
a[i]=pos[x];
}
printf("%d\n",Slove(m));
}
}
!!!
> map<int,int >pos;
> int pos=lower_bound(f+1,f+c,t)-f;
> 二分法找到比t大的第一个位置
最大公共子序列:找对应的最长上升子序列的个数
MLE
#include<bits/stdc++.h>
using namespace std;
int dp[11111][11111];
int T,len1,len2;
int s1[11111],s2[11111];
int main()
{
scanf("%d",&T);
while(T--)
{
memset(dp,0,sizeof(dp));
memset(s1,0,sizeof(s1));
memset(s2,0,sizeof(s2));
scanf("%d%d",&len1,&len2);
for(int i=0;i<len1;i++)
{
scanf("%d",&s1[i]);
}
for(int i=0;i<len2;i++)
{
scanf("%d",&s2[i]);
}
for(int i=1;i<=len1;i++)
{
for(int j=1;j<=len2;j++)
{
if(s1[i-1]==s2[j-1])
dp[i][j]=dp[i-1][j-1]+1;
else
dp[i][j]=max(dp[i-1][j],dp[i][j-1]);
}
}
printf("%d\n",dp[len1][len2]);
}
}