分ai==bj和ai!=bj分别转移状态
#include <bits/stdc++.h> using namespace std; const int maxn = 3005; const int INF = (1<<31); int dp[maxn][maxn]; int main() { int n,ans=0; int a[maxn],b[maxn]; a[0]=b[0]=-INF; memset(dp,0,sizeof(dp)); 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]); for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) { if(a[i]!=b[j]) dp[i][j]=dp[i-1][j]; else { for(int k=1;k<j;k++) if(b[j]>b[k]) dp[i][j]=max(dp[i][j],dp[i-1][k]); dp[i][j]++;//注意这一步,最后再加1 } an***ax(ans,dp[i][j]); } printf("%d\n",ans); return 0; }
O(n^2)算法详解可参照算法竞赛进阶指南P261或该文档https://wenku.baidu.com/view/3e78f223aaea998fcc220ea0.html
#include <bits/stdc++.h> using namespace std; const int maxn = 3005; const int INF = (1<<21); int dp[maxn][maxn]; int main() { int n,ans=0; int a[maxn],b[maxn]; a[0]=b[0]=-INF; memset(dp,0,sizeof(dp)); 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]); for(int i=1;i<=n;i++) { int v=0; if(b[0]<a[i]) v=dp[i-1][0]; for(int j=1;j<=n;j++) { if(a[i]==b[j]) dp[i][j]=v+1; else dp[i][j]=dp[i-1][j]; if(b[j]<a[i]) v=max(v,dp[i-1][j]); } } for(int i=1;i<=n;i++) an***ax(ans,dp[n][i]); printf("%d\n",ans); return 0; }