AT2418 共通部分文字列 题解

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

题意

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

解法

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

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

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

动态规划转移方程

观察这张图,对于 a i − 1 , j − 1 \mathit{a}_{i-1,j-1} ai1,j1 来说,它的值有两种可能,取决于字符 x i x_i xi y j y_j yj 这两个字符是否相等。

a i , j = { 0 i = 1 ∨ j = 0 a i − 1 , j − 1 + 1 i , j > 0 ∧ x i = y i 0 i , j > 0 ∧ x i ≠ y i \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;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值