解题思路:
f[ i ] [ j ] 表示匹配完第一条的第 i 个和第二条的第 j 个(均可以与空格进行匹配);
① f [ i - 1 ] [ j ] + v (第一条第 i 个与空格匹配后增加的相似度) ,当该值大于 f 原值时就用它优化 f;
② f [ i ] [ j - 1 ] + v (第二条第 j 个与空格匹配后增加的相似度) ,当该值大于 f 原值时就用它优化 f;
③ f [ i - 1 ] [ j - 1 ] + v(第一条第 i 个与第二条第 j 个匹配后增加的相似度) ,当该值大于 f 原值时就用它优化 f;
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
#include<cmath>
#include<queue>
#include<vector>
#define ll long long
using namespace std;
int getint()
{
int i=0,f=1;char c;
for(c=getchar();(c<'0'||c>'9')&&c!='-';c=getchar());
if(c=='-')c=getchar(),f=-1;
for(;c>='0'&&c<='9';c=getchar())i=(i<<3)+(i<<1)+c-'0';
return i*f;
}
const int N=105;
const int g[5][5]={5,-1,-2,-1,-3,
-1,5,-3,-2,-4,
-2,-3,5,-2,-2,
-1,-2,-2,5,-1,
-3,-4,-2,-1,0};
int T,n,m,a[N],b[N],f[N][N];
char s[N],t[N];
int main()
{
//freopen("lx.in","r",stdin);
T=getint();
while(T--)
{
memset(f,0,sizeof(f));
n=getint();scanf("%s",s+1);
m=getint();scanf("%s",t+1);
for(int i=1;i<=n;i++)
if(s[i]=='A')a[i]=0;
else if(s[i]=='C')a[i]=1;
else if(s[i]=='G')a[i]=2;
else if(s[i]=='T')a[i]=3;
for(int i=1;i<=m;i++)
if(t[i]=='A')b[i]=0;
else if(t[i]=='C')b[i]=1;
else if(t[i]=='G')b[i]=2;
else if(t[i]=='T')b[i]=3;
for(int i=1;i<=n;i++)
f[i][0]=f[i-1][0]+g[a[i]][4];
for(int i=1;i<=m;i++)
f[0][i]=f[0][i-1]+g[4][b[i]];
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
f[i][j]=max(f[i-1][j-1]+g[a[i]][b[j]],max(f[i-1][j]+g[a[i]][4],f[i][j-1]+g[4][b[j]]));
cout<<f[n][m]<<'\n';
}
}