Catching Cheaters CodeForces - 1446B
原题链接
考察:线性DP
错误思路:
求出最长公共子序列再dfs回溯枚举长度.
错误原因:
不一定只存在一个最长公共子序列.比如样例2.
正确思路:
是dp(...),定义 f[i][j] 为以1~i,1~j构成的最长公共子序列的最大S值,且A子串以i结尾,b子串由j结尾.这里其实类似最大连续子段和的问题,我们不确定结果是以什么结尾,所以每个取max
If a[i]==b[j] f[i][j] = f[i-1][j-1]+4-2.
else f[i][j] = max(f[i-1][j],f[i][j-1])-1.
Code
#include <iostream>
#include <cstring>
using namespace std;
typedef long long LL;
const int N = 5010;
char a[N],b[N];
int f[N][N],m,n;
int main()
{
scanf("%d%d",&n,&m);
scanf("%s%s",a+1,b+1);
int res = 0;
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]+2,f[i][j]);
else f[i][j] = max(f[i-1][j],f[i][j-1])-1;
f[i][j] = max(f[i][j],0);
res = max(f[i][j],res);
}
printf("%d\n",res);
return 0;
}