https://ac.nowcoder.com/acm/contest/1041/B
发现水题好像不太会。。。。得补下基础了
这题要联想到LIS是以一个数字为结尾最长的状态,再联想到LCS时以s串的前i个字母和t串的前j个字母的最大公共子序列的状态。
于是设出f[i][j]表示A的前i个数字和以B[j]为结尾的最长上升的长度,那么就很好转移了,
如果a[i]==b[j],那么f[i][j]=max(f[i-1][k]+1) b[k]<b[j]=a[i],那么因为a[i]是从左到右枚举的,所以枚举b[j]的时候可以顺便把f[i-1][k]的最大值给维护了。
#include<bits/stdc++.h>
#define maxl 3010
using namespace std;
int n;
int a[maxl],b[maxl];
int f[maxl][maxl];
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;i++)
scanf("%d",&a[i]);
for(int i=1;i<=n;i++)
scanf("%d",&b[i]);
int tmp,ans=0;
for(int i=1;i<=n;i++)
{
tmp=0;
for(int j=1;j<=n;j++)
{
if(a[i]==b[j])
f[i][j]=tmp+1;
else
f[i][j]=f[i-1][j];
if(b[j]<a[i])
tmp=max(f[i-1][j],tmp);
ans=max(f[i][j],ans);
}
}
printf("%d",ans);
return 0;
}