AT_dp_f LCS
设计 \(f(i,j)\) 表示用掉 \(A\) 序列前 \(i\) 位和 \(B\) 序列前 \(j\) 位所得最长长度。
可知 \(f(i,j)=\max\set{f(i-1,j),f(i,j-1),f(i-1,j-1)+[A_i==B_j]}\),时间复杂度 \(O(n^2)\)。
输出方案并不难处理,转移的时候记录并倒序处理即可。
#include<bits/stdc++.h>
using namespace std;
const int N=3033;
struct num{
int a,b;
char c;
} note[N][N],tmp;
int dp[N][N],n,m;
char A[N],B[N];
stack<char> st;
int main(){
scanf("%s%s",A+1,B+1),n=strlen(A+1),m=strlen(B+1);
for(int i=1;i<=n;i++) for(int j=1;j<=m;j++){
if(dp[i-1][j]>dp[i][j-1])
dp[i][j]=dp[i-1][j],note[i][j]={i-1,j,'%'};
else
dp[i][j]=dp[i][j-1],note[i][j]={i,j-1,'%'};
if(A[i]==B[j]&&dp[i][j]<dp[i-1][j-1]+1)
dp[i][j]=dp[i-1][j-1]+1,note[i][j]={i-1,j-1,A[i]};
}
for(int i=n,j=m;i>0&&j>0;){
if(note[i][j].c!='%') st.push(note[i][j].c);
tmp=note[i][j],i=tmp.a,j=tmp.b;
}
while(!st.empty()) putchar(st.top()),st.pop();
return 0;
}

浙公网安备 33010602011771号