题解里面很详细。
复习了最长公共子序列——动态规划:
记dp[i][j]为A的前i个字符和B的前j个字符的最长公共子序列,
若Ai=Bj,则dp[i][j]等于dp[i-1][j-1]+1;
若Ai≠Bj,则dp[i][j]为max(dp[i-1][j],dp[i][j-1])。如果Ai属于最长公共子序列,那么Bj必定和最长公共子序列无关,则dp[i][j]==dp[i][j-1],Bj同理,若Ai、Bj均不属于最长公共子序列,dp[i][j]=dp[i-1][j-1]=dp[i-1][j]=dp[i][j-1];
#include<fstream>
#include<iostream>
#include<string>
#include<math.h>
#include<string.h>
using namespace std;
#define FOR(i,b,e) for(int i=(b);i<=(e);i++)
#define FORE(i,b,e) for(int i=(b);i>=(e);i--)
#define maxnum 2200
int f[maxnum][maxnum];
int dp[maxnum][maxnum][2];
int main()
{
#ifdef DEBUG_
ifstream fin("G:/1.txt");
#define cin fin
#endif
string a,b;
cin>>a;
cin>>b;
int alen=a.length(),blen=b.length();
memset(f,0,sizeof(0));
memset(dp,0,sizeof(0));
FOR(i,1,alen)
FOR(j,1,blen){
if(a[i-1]==b[j-1])
f[i][j]=f[i-1][j-1]+1;
else
f[i][j]=0;
}
FOR(i,1,alen)
FOR(j,1,blen){
if(f[i][j]>=3){
dp[i][j][1]=max(dp[i-3][j-3][0]+3,dp[i][j][1]);
if(f[i][j]>3)
dp[i][j][1]=max(dp[i-1][j-1][1]+1,dp[i][j][1]);
}
dp[i][j][0]=max(max(dp[i-1][j][0],dp[i][j-1][0]),dp[i][j][1]);
}
cout<<dp[alen][blen][0]<<endl;
return 0;
}