题目链接:点击打开链接
1003-LCIS
Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 243 Accepted Submission(s): 98
Problem Description
Alex has two sequences
a
1
,a
2
,...,a
n![]()
and
b
1
,b
2
,...,b
m![]()
. He wants find a longest common subsequence that consists of consecutive values in increasing order.
Input
There are multiple test cases. The first line of input contains an integer
T
, indicating the number of test cases. For each test case:
The first line contains two integers n
and
m
(1≤n,m≤100000)
-- the length of two sequences. The second line contains
n
integers:
a
1
,a
2
,...,a
n![]()
(1≤a
i
≤10
6
)
. The third line contains
n
integers:
b
1
,b
2
,...,b
m![]()
(1≤b
i
≤10
6
)
.
There are at most 1000
test cases and the sum of
n
and
m
does not exceed
2×10
6![]()
.
The first line contains two integers n
There are at most 1000
Output
For each test case, output the length of longest common subsequence that consists of consecutive values in increasing order.
Sample Input
3 3 3 1 2 3 3 2 1 10 5 1 23 2 32 4 3 4 5 6 1 1 2 3 4 5 1 1 2 1
Sample Output
1 5 0
Source
题解:
令f(i)是以a i结尾的最大值, g(i)是以bi结尾的最大值. 答案就是maxai=bj{min(f(i),g(j)}. f和g随便dp一下就出来了.
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
const int MAXN=1e5+10;
int n,m;
int a[MAXN],b[MAXN];
int dp1[MAXN],dp2[MAXN];
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
scanf("%d %d",&n,&m);
for(int i=0;i<MAXN;i++)
{
a[i]=b[i]=dp1[i]=dp2[i]=0;
}
// 这里用 for来初始化数组也可以,用 memset一般初始化一些较大的结构体和数组比较省时
// 像空间比较小的如 100,用 for就比较快
// memset(a,0,sizeof(a));
// memset(b,0,sizeof(b));
// memset(dp1,0,sizeof(dp1));
// memset(dp2,0,sizeof(dp2));
for(int i=0;i<n;i++)
{
scanf("%d",&a[i]);
dp1[a[i]]=max(dp1[a[i]],dp1[a[i]-1]+1);
}
for(int i=0;i<m;i++)
{
scanf("%d",&b[i]);
dp2[b[i]]=max(dp2[b[i]],dp2[b[i]-1]+1);
}
int ans=0;
for(int i=0;i<n;i++)
{
ans=max(ans,min(dp1[a[i]],dp2[a[i]]));
}
// for(int i=0;i<m;i++) 任意找一个(a或 b) dp都可以
// {
// ans=max(ans,min(dp1[b[i]],dp2[b[i]]));
// }
printf("%d\n",ans);
}
return 0;
}