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;
}
posted @ 2026-02-08 16:05  2025ing  阅读(3)  评论(0)    收藏  举报