原题链接
题意:给你一个长度为n,m的字符串a,b。求a中任取一个子串C,和b中任取一个子串D。最大的
L
C
S
(
C
,
D
)
−
l
e
n
(
C
)
−
l
e
n
(
D
)
LCS(C,D)-len(C)-len(D)
LCS(C,D)−len(C)−len(D)
题解:
设
f
[
i
]
[
j
]
f[i][j]
f[i][j]表示以a中以 i,b中以 j 结尾的子串的最大值
f
[
i
]
[
j
]
=
m
a
x
(
f
[
i
−
1
]
[
j
−
1
]
)
,
0
)
+
2
i
f
(
a
[
i
]
=
=
b
[
j
]
)
f
[
i
]
[
j
]
=
m
a
x
(
f
[
i
−
1
]
[
j
]
,
f
[
i
]
[
j
−
1
]
)
−
1
e
l
s
e
f[i][j]=max(f[i-1][j-1]),0)+2 ~~~~~~~~~if(a[i]==b[j])\\ f[i][j]=max(f[i-1][j],f[i][j-1])-1 ~~~~~~~~~else
f[i][j]=max(f[i−1][j−1]),0)+2 if(a[i]==b[j])f[i][j]=max(f[i−1][j],f[i][j−1])−1 else
如果
a
[
i
]
=
=
b
[
j
]
a[i]==b[j]
a[i]==b[j]则lcs会增加1,则贡献为4-1-1=2
若不一样则lcs不会增加,两个串中的一个串长度增加1,贡献减1。
注意
a
[
i
]
=
=
b
[
j
]
a[i]==b[j]
a[i]==b[j]的时候记得和0取个max,否则可能变成负数+2,但实际上肯定抛弃掉负数的串。0+2更好。
以后遇到子序列要多想以某个结尾来表示状态
#include<bits/stdc++.h>
using namespace std;
const int N=5005;
int f[N][N];
char a[N],b[N];
int main()
{
int n,m;
cin>>n>>m;
int ans=0;
cin>>a+1>>b+1;
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
{
if(a[i]==b[j])f[i][j]=max(f[i-1][j-1],0)+2;
else f[i][j]=max(f[i-1][j],f[i][j-1])-1;
ans=max(ans,f[i][j]);
}
cout<<ans;
return 0;
}