LCS标准

atcoder dp 题单 中的LCS

https://atcoder.jp/contests/dp/tasks)

code

#include<bits/stdc++.h>
using namespace std;
//"O campeão tem nome, e se chama Charles Oliveira!"
#define int long long
#define endl '\n'
#define ep emplace
#define pob 
#define ll long long
#define pb push_back
#define pof pop_front
#define pob pop_back
#define all(a) a.begin(),a.end()
#define rall(a) a.rbegin(),a.rend()
#define mod 998244353
#define MOD 1000000007

using ld = long double;
using ui = unsigned;
using ull = unsigned long long;
using i128 = __int128;

void solve() {
    string s,t;cin>>s>>t;
    int ns=s.length(),nt=t.length();
    vector<vector<int>>dp(ns+1,vector<int>(nt+1));
    vector<char>ans;
    for(int i=1;i<=ns;i++){
        for(int j=1;j<=nt;j++){
            //dp[i][j]说的就是s[i]和t[j]
            //单元格 dp[i][j]:表示 S1 的前 i 个字符和 S2 的前 j 个字符的最长公共子序列长度。
            dp[i][j]=max(dp[i-1][j],dp[i][j-1]);
            //就是说是,保留s[i-1]还是保留t[j-1],因为字符不相等,只能取掉一个,取掉哪个呢,就是取大的那一个
            if(s[i-1]==t[j-1])dp[i][j]=dp[i-1][j-1]+1;//这里直接等于dp[i-1][j-1]+1就好了,没必要就是跟dp[i][j]再比一次
        }
    }
    //洛谷上有超级详细的题解
(https://www.luogu.com.cn/problem/solution/AT_dp_f)
    int i=ns,j=nt;
    while(dp[i][j]>0){
        if(s[i-1]==t[j-1]){
            ans.push_back(s[i-1]);
            i--,j--;
        }else{
            if(dp[i][j]==dp[i-1][j])i--;
            else j--;
        }
    }
    for(int i=ans.size()-1;i>=0;i--)cout<<ans[i];  
}
signed main(){
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    cout.tie(nullptr);
    int t=1;
    //cin>>t;
    while(t--)solve();
}
posted @ 2026-03-10 13:28  Time_q  阅读(3)  评论(0)    收藏  举报