LCS变体。
传送门:http://acm.hdu.edu.cn/showproblem.php?pid=1080
#include <map>
#include <set>
#include <queue>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <algorithm>
using namespace std;
//最多有100个字符;
char s1[105],s2[105];
int b1[105],b2[105];
int dp[105][105];
void Deal_with() {
int T;
scanf("%d",&T);
int len1 , len2;
int r[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}
};
while(T--) {
scanf("%d %s",&len1,s1+1);
scanf("%d %s",&len2,s2+1);
//预处理
for(int i = 1 ; i <= len1 ; i ++) {
if(s1[i] =='A') b1[i] = 0;
else if(s1[i] == 'C') b1[i] = 1;
else if(s1[i] == 'G') b1[i] = 2;
else b1[i] = 3;
}
for(int i = 1 ; i <= len2 ; i ++) {
if(s2[i] =='A') b2[i] = 0;
else if(s2[i] == 'C') b2[i] = 1;
else if(s2[i] == 'G') b2[i] = 2;
else b2[i] = 3;
}
memset(dp,0,sizeof(dp));
for(int i = 1 ; i <= len2 ; i ++) {
dp[0][i] = dp[0][i-1] + r[b2[i]][4];
}
for(int i = 1 ; i <= len1 ; i ++) {
dp[i][0] = dp[i-1][0] + r[4][b1[i]];
}
for(int i = 1 ; i <= len1 ; i ++) {
for(int j = 1 ; j <= len2 ; j ++) {
dp[i][j] = max(dp[i-1][j-1]+r[b1[i]][b2[j]],max(dp[i-1][j]+r[b1[i]][4],dp[i][j-1]+r[4][b2[j]]));
}
}
//for(int i = 0 ; i <= len1 ; i ++) {
// for(int j = 0 ; j <= len2 ; j ++) {
// printf("%d ",dp[i][j]);
// }
// puts("");
// }
printf("%d\n",dp[len1][len2]);
}
}
int main(void) {
// freopen("a.in","r",stdin);
Deal_with();
return 0;
}
/*
最长公共子序列的一个变体;
两个连接只有三种形式,-X,X- , XX;
*/