
注释1是把三重循环优化成二重(maxlen只跟a[i]和前b的前j-1个前缀有关,而j是从小到大枚举的,可以在枚举的过程中处理)
注释2是把二维数组优化为一维(观察可知f[i][j]可以被f[j]覆盖掉而不影响结果)
优化完成后的代码就非常反直觉了(在我看来),所以以后dp题最好先自己把朴素的思路想出来,再一步步优化
#include<bits/stdc++.h>
using namespace std;
#define fr first
#define se second
typedef pair<int, int> PII;
typedef long long LL;
typedef unsigned long long ULL;
const int INF = 0X3f3f3f3f, N = 3000 + 10, MOD = 1e9 + 10;
int a[N],b[N];
// int f[N][N]; 2
int f[N];
void work() {
int n;
cin>>n;
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++){
int maxlen=1;
for(int j=1;j<=n;j++){
// f[i][j]=f[i-1][j]; 2
if(a[i]==b[j]){
// int maxlen=1; 1
// for(int k=1;k<j;k++){ 1
// if(a[i]>b[k]) 1
// maxlen=max(maxlen,f[i-1][k]+1); 1
// } 1
f[j]=max(f[j],maxlen);
}
if(a[i]>b[j]) maxlen=max(maxlen,f[j]+1);
}
}
int res=0;
for(int i=1;i<=n;i++){
// res=max(res,f[n][i]); 2
res=max(res,f[i]);
}
cout<<res<<endl;
}
signed main() {
work();
return 0;
}