一道练习最长公共子串的题。
题意
给定两个字符串,让你求出两个字符串的最长公共子串。
解法
求最长公共子串,所以考虑动态规划,时间复杂度为 O(nm)O(nm)O(nm),其中 nnn 和 mmm 是两个子序列的长度。
因为动态规划时有可能访问到 −1-1−1 这个地址,为防止数组越界,我们要在字符串前加上一个或多个字符防止越界。
坑点:我们不要开 int 型变量,会出锅的,要开 short 型变量。
动态规划转移方程

观察这张图,对于 ai−1,j−1\mathit{a}_{i-1,j-1}ai−1,j−1 来说,它的值有两种可能,取决于字符 xix_ixi 和 yjy_jyj 这两个字符是否相等。
ai,j={0i=1∨j=0ai−1,j−1+1i,j>0∧xi=yi0i,j>0∧xi≠yi\mathit{a}_{i,j}=\begin{cases}0&i=1 \lor j=0\\ \mathit{a}_{i-1,j-1}+1&i,j>0 \land x_i = y_i \\ 0 & i,j>0 \land x_i \ne y_i \end{cases}ai,j=⎩⎨⎧0ai−1,j−1+10i=1∨j=0i,j>0∧xi=yii,j>0∧xi=yi
代码
#include<bits/stdc++.h>
std::string s1,s2;
short f[4010][4010],ans,s1s,s2s;
int main()
{
std::cin>>s1>>s2,s1="0"+s1,s2="0"+s2,s1s=s1.size(),s2s=s2.size();
for(int i=1;i<s1s;i++) for(int j=1;j<s2s;j++) if(s1[i]==s2[j]) f[i][j]=f[i-1][j-1]+1;
for(int i=1;i<s1s;i++) for(int j=1;j<s2s;j++) ans=std::max(ans,f[i][j]);
std::cout<<ans<<std::endl;
return 0;
}

被折叠的 条评论
为什么被折叠?



