CodeForces1447D
题意
给定两个长度为5000的字符串s和t,分别从中找到一个子串ss和tt,使得4*lcs(ss,tt)-len(ss)-len(tt)的值最大。
分析
5000! lcs! 很容易想到最长公共子序列O(N^2)的dp求法,类似的,我们定义dp[i][j]表示以s[i]结尾的子串和以t[j]结尾的子串的最大计算值,注意一定是以这两个字符结尾,这样统计才不重不漏,而子串的左端点其实无需考虑,只需要通过取max更新答案。
当两个字符相等,显然lcs加1,两个子串长度也分别加1,总的值加2,当两个字符不等,按照lcs的做法,这里的一个子串长度加1,另一个不变。
代码
#include <bits/stdc++.h>
using namespace std;
const int N=5050;
char s[N],t[N];
int n,m;
// 不用管子串的开头,dp[i][j]表示以s[i]结尾的子串和以t[j]结尾的子串的最大计算值
int dp[N][N];
int main(){
scanf("%d%d",&n,&m);
scanf("%s",s+1);
scanf("%s",t+1);
int ans=0;
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
if(s[i]==t[j]){
dp[i][j]=dp[i-1][j-1]+2;
}else{
dp[i][j]=max(0,max(dp[i][j-1],dp[i-1][j])-1);
}
ans=max(ans,dp[i][j]);
}
}
printf("%d\n",ans);
return 0;
}
目录