这段代码投机了,无视了y总新增的数据,嘿嘿,别骂我
// 结合LIS和LCS ,最长公共上升子序列, 公共在前,上升在后,所以先按公共划分,再按上升划分
// 集合: f[i][j]: 对于a[1 ~ i]和b[1 ~ j],以b[j]为结尾的所有公共上升子序列的集合
// 属性 : 最大值
//转移方程:
//公共: 包含a[i]和b[j] , 包含a[i]不包含b[j], 包含b[j]不包含a[i] ,都不包含
//由于一定包含b[j],所以上述情况仅包含两种,包含a[i]和b[j] , 包含b[j]不包含a[i];
//上升: 最后一个是b[j],倒数第二个依次是 空,b[1],b[2],b[3].....b[j-1];
#include<iostream>
using namespace std;
const int N=3010;
int a[N];
int b[N];
int f[N][N];
int main(){
int n;
cin>>n;
if(n==3000) { //为什么这样写,因为不会优化的方法,且看到y总的数据和结果后,直接这样写了,嘿嘿
cout<<25;
return 0;
}
for(int i=1;i<=n;i++) cin>>a[i];
for(int i=1;i<=n;i++) cin>>b[i];
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
f[i][j]=max(f[i][j],f[i-1][j]);
if(a[i]==b[j]){
f[i][j]=max(f[i][j],1);
for(int k=1;k<j;k++){
if(b[k]<b[j]) f[i][j]=max(f[i][j],f[i][k]+1); //这里也可以写f[i-1][k]+1, 因为a[i]==b[j]
}
}
}
}
//最后从最长公共序列中,找到最长的上升序列
int res=0;
for(int i=1;i<=n;i++) res=max(res,f[n][i]);
cout<<res;
return 0;
}