CF10D 最长公共上升子序列 题解报告
【题目大意】
给定两个序列$a,b$,求最长公共上升子序列。
【思路分析】
这里mark一下最简单的$n^3$做法(并且不记录最长公共上升子序列的数):
$f[i][j]$表示匹配到$a[i]$和$b[j]$的最长公共上升子序列的长度,转移时分情况讨论:
1.$a[i]=b[j]$,则$f[i][j]=max(f[i][j],f[k][j-1]+1)(k\in[0,i-1]\&\&a[i]>a[k])$,注意给$a[0]$赋值为负无穷
2.$a[i]\ne b[j]$,则$f[i][j]=max(f[i-1][j],f[i][j-1])$
还有一种$n^2$做法贴个链接叭QwQ
【代码实现】
1 #include<cstdio> 2 #include<iostream> 3 #include<cstring> 4 #include<algorithm> 5 #include<cmath> 6 #include<queue> 7 #define g() getchar() 8 #define rg register 9 #define go(i,a,b) for(rg int i=a;i<=b;i++) 10 #define back(i,a,b) for(rg int i=a;i>=b;i--) 11 #define db double 12 #define ll long long 13 #define il inline 14 #define pf printf 15 #define mem(a,b) memset(a,b,sizeof(a)) 16 using namespace std; 17 int fr(){ 18 int w=0,q=1; 19 char ch=g(); 20 while(ch<'0'||ch>'9'){ 21 if(ch=='-') q=-1; 22 ch=g(); 23 } 24 while(ch>='0'&&ch<='9') w=(w<<1)+(w<<3)+ch-'0',ch=g(); 25 return w*q; 26 } 27 const int N=502; 28 int n,m,a[N],b[N],f[N][N]; 29 int main(){ 30 //freopen("","r",stdin); 31 //freopen("","w",stdout); 32 n=fr(); 33 go(i,1,n) a[i]=fr(); 34 m=fr(); 35 go(i,1,m) b[i]=fr(); 36 a[0]=-1; 37 go(i,1,n) go(j,1,m){ 38 if(a[i]==b[j]) 39 go(k,0,i-1) if(a[i]>a[k]) f[i][j]=max(f[i][j],f[k][j-1]+1); 40 else f[i][j]=max(f[i-1][j],f[i][j-1]); 41 } 42 pf("%d\n",f[n][m]); 43 return 0; 44 }