题解
LCS就是经典的dp问题,所以看到这道题时觉得大概与LCS差不多,只是多加一些条件罢了。
LCS的转移方程:\(dp[i][j]= \begin{cases} max(dp[i-1][j],dp[i][j-1]) \quad a[i]!=a[j] \\ dp[i-1][j-1]+1 \quad a[i]==a[j] \end{cases}\)
这道题添加了一个字串长度参数,如果\(a[i]==a[j]\),根据公式\(dp[i][j]\)要\(+4-1-1\),也就是\(dp[i][j]=dp[i-1][j-1]+2\);其他情况,因为字串长度加1,所以要在原来的基础上减1,也就是\(dp[i][j]=max(dp[i-1][j],dp[i][j-1])-1\)。此外要注意一件事情,字串为空时答案是0,也就是答案一定大于等于0,所以如果\(dp[i][j]<0\),\(dp[i][j]=0\)。
AC代码
#include<bits/stdc++.h>
using namespace std;
const int N=5010;
int dp[N][N];
char a[N],b[N];
int main()
{
int n,m,ans=0;
scanf("%d%d%s%s",&n,&m,a+1,b+1);
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
if(a[i]==b[j]) dp[i][j]=dp[i-1][j-1]+2;
else dp[i][j]=max(0,max(dp[i-1][j],dp[i][j-1])-1);
ans=max(ans,dp[i][j]);
}
}
printf("%d",ans);
return 0;
}