F - LCS 题解(最长公共子序列记录路径)
题目链接
题目大意
给你两个字符串,任意写出一个最长公共子序列
字符串长度小于3e3
题目思路
就是一个记录路径有一点要注意
找了好久的bug
不能直接\(dp[i][j]=dp[i-1][j-1]+1\),就代表\(s[i]=t[j]\)
例如aacb和aaac
\(dp[4][4]=dp[3][3]+1\)
但是s[4]!=t[4],所以还要判断s[i]=s[j]
代码
#include<set>
#include<map>
#include<queue>
#include<stack>
#include<cmath>
#include<cstdio>
#include<vector>
#include<string>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<unordered_map>
#define fi first
#define se second
#define debug printf(" I am here\n");
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> pii;
const ll INF=0x3f3f3f3f3f3f3f3f;
const int maxn=3e3+5,inf=0x3f3f3f3f,mod=2017;
const double eps=1e-10;
char s[maxn],t[maxn];
int dp[maxn][maxn];
vector<char> vec;
int main(){
scanf("%s %s",s+1,t+1);
int ds=strlen(s+1),dt=strlen(t+1);
for(int i=1;i<=ds;i++){
for(int j=1;j<=dt;j++){
if(s[i]==t[j]){
dp[i][j]=dp[i-1][j-1]+1;
}else{
dp[i][j]=max(dp[i-1][j],dp[i][j-1]);
}
}
}
while(ds>0&&dt>0){
if(dp[ds-1][dt-1]+1==dp[ds][dt]&&s[ds]==t[dt]){
vec.push_back(s[ds]);
ds--,dt--;
}else if(dp[ds-1][dt]==dp[ds][dt]){
ds--;
}else if(dp[ds][dt-1]==dp[ds][dt]){
dt--;
}
}
reverse(vec.begin(),vec.end());
for(int i=0;i<vec.size();i++){
printf("%c",vec[i]);
}
return 0;
}
不摆烂了,写题