问题描述

解题报告
此题是最长公共子数组,注意与最长公共子序列不同;
对于最长公共子数组,
d
p
[
i
]
[
j
]
dp[i][j]
dp[i][j] 表示子串以
A
[
i
]
A[i]
A[i] 和
B
[
j
]
B[j]
B[j] 结尾的最长公共子数组。
i
f
A
[
i
]
=
=
B
[
j
]
d
p
[
i
]
[
j
]
=
d
p
[
i
−
1
]
[
j
−
1
]
+
1
i
f
A
[
i
]
≠
B
[
j
]
d
p
[
i
]
[
j
]
=
0
if A[i]==B[j] \;dp[i][j]=dp[i-1][j-1]+1\\ if A[i]\ne B[j]\;dp[i][j]=0
ifA[i]==B[j]dp[i][j]=dp[i−1][j−1]+1ifA[i]=B[j]dp[i][j]=0
对于最长公共子序列,
d
p
[
i
]
[
j
]
dp[i][j]
dp[i][j] 表示数组
A
[
1
,
⋯
,
i
]
A[1,\cdots ,i]
A[1,⋯,i] 和数组
B
[
1
,
⋯
,
j
]
B[1,\cdots,j]
B[1,⋯,j] 的最长公共子序列的长度
i
f
A
[
i
]
=
=
B
[
j
]
d
p
[
i
]
[
j
]
=
d
p
[
i
−
1
]
[
j
−
1
]
+
1
i
f
A
[
i
]
≠
B
[
j
]
d
p
[
i
]
[
j
]
=
m
a
x
(
d
p
[
i
−
1
]
[
j
]
,
d
p
[
i
]
[
j
−
1
]
)
if A[i]==B[j]\;dp[i][j]=dp[i-1][j-1]+1\\ if A[i] \ne B[j]\;dp[i][j]=max(dp[i-1][j],dp[i][j-1])
ifA[i]==B[j]dp[i][j]=dp[i−1][j−1]+1ifA[i]=B[j]dp[i][j]=max(dp[i−1][j],dp[i][j−1])
补充:这里最长公共子串 为什么要求是以A[i] 和以 A[j] 结尾的,如果不指定,那么A[i]==A[j] 时,无法得到dp[i][j]=dp[i-1][j-1]+1这个结论,因为无法保证A[i-1]==A[j-1]
实现代码
- 最长公共子数组
class Solution {
public:
int findLength(vector<int>& A, vector<int>& B) {
int m=A.size(),n=B.size(),ans=0;
vector<vector<int>>dp(m+1,vector<int>(n+1,0));
for(int i=1;i<=m;i++){
for(int j=1;j<=n;j++){
if(A[i-1]==B[j-1]){
dp[i][j]=dp[i-1][j-1]+1;
ans=max(ans,dp[i][j]);
}
}
}
return ans;
}
};
- 最长公共子序列
class Solution{
public:
int FindLength(vector<int>& A,vector<int>& B){
int m=A.size(),n=B.size(),ans=0;
vector<vector<int>>dp(m+1,vector<int>(n+1,0));
for(int i=1;i<=m;i++){
for(int j=1;j<=n;j++){
if(A[i-1]==B[j-1]){
dp[i][j]=dp[i-1][j-1];
}
else{
dp[i][j]=max(dp[i-1][j],dp[i][j-1]);
}
}
}
return dp[m][n];
}
};