题目链接:https://ac.nowcoder.com/acm/contest/1041/B
题意:求两个序列的最长公共上升子序列
一开始写的状态是以Ai,Bj为结尾的LCIS的长度,但发现这样的转移方程写出来是O(N^4)的。实际的状态应该是f[i][j]表示考虑A1到Ai,B1到Bj,以Bj为结尾的LCIS的长度,那么有转移方程:
f[i][j]=f[i-1][j] (Ai!=Bj)
f[i][j]=max(f[i-1][k])+1 0<=k<=j-1且Bk<Bj (Ai=Bj)
可以在枚举j时用一个变量维护f[i-1][k]的最大值(而且要满足Bk<Bj=Ai),这样复杂度降为O(n^2)
#include<bits/stdc++.h> using namespace std; const int N=3000+10; int a[N],b[N],f[N][N],n,i,j,x; int main(){ cin>>n; for (i=1;i<=n;i++) cin>>a[i]; for (i=1;i<=n;i++) cin>>b[i]; a[0]=b[0]=-1e9; for (i=1;i<=n;i++){ int x=0; for (j=1;j<=n;j++){ if (a[i]==b[j]) f[i][j]=max(f[i-1][j],x+1); else f[i][j]=f[i-1][j]; if (b[j]<a[i]) x=max(x,f[i-1][j]); } } int ans=0; for (i=1;i<=n;i++) ans=max(ans,f[n][i]); cout<<ans<<endl; return 0; }