AT2418 共通部分文字列 题解

一道练习最长公共子串的题。

题意

给定两个字符串,让你求出两个字符串的最长公共子串。

解法

求最长公共子串,所以考虑动态规划,时间复杂度为 O(nm)O(nm)O(nm),其中 nnnmmm 是两个子序列的长度。

因为动态规划时有可能访问到 −1-11 这个地址,为防止数组越界,我们要在字符串前加上一个或多个字符防止越界。

坑点:我们不要开 int 型变量,会出锅的,要开 short 型变量。

动态规划转移方程

观察这张图,对于 ai−1,j−1\mathit{a}_{i-1,j-1}ai1,j1 来说,它的值有两种可能,取决于字符 xix_ixiyjy_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=0ai1,j1+10i=1j=0i,j>0xi=yii,j>0xi=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;
}
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值