题目分析:
•这一题是LCS,只是一个变形而已,有三种情况 (dist[ ][ ]为两符号所得的分数):
•1、s1取第i个字母,s2取“ - ”:dp[i][j] = dp[i-1,j] + dist[s1[i],'-'];
•2、 s1取“ - ”,s2取第j个字母:dp[i][j] = dp[i,j-1] + dist['-',s2[j]];
•3、 s1取第i个字母,s2取第j个字母:dp[i][j] = dp[i-1,j-1] + dist[s1[i],s2[j]]
• 即dp[i,j]=max( dp[i-1,j] + dist[s1[i],'-'], dp[i,j-1]+dist['-',s2[j]], dp[i-1,j-1]+dist[s1[i],s2[j]]);
值得注意的是边界的问题,如何去初始化:
•考虑边界条件,这道题为i或j为0的情况。当i=j=0时,即为dp[0,0],这是在计算dp[1,1]时用到的,根据dp[1,1]=dp[0,0] + dist[s1[i], s2[j]],明显有dp[0,0] = 0。
•当i=0时,dp[0,j] = dp[0,j-1] + dist['-',s2[j]]来计算
•当j=0时,dp[i,0] = dp[i-1,0] + dist[s1[i],'-']来计算
#include<iostream>
#include<string>
#include<algorithm>
using namespace std;
int s[20][20];
int dp[101][101];
void init()
{
int a=0,c=2,g=6,t=19;
s[a][a]=s[c][c]=s[g][g]=s[t][t]=5;
s[a][c]=s[c][a]=-1;
s[a][g]=s[g][a]=-2;
s[a][t]=s[t][a]=-1;
s[a][1]=s[1][a]=-3;
s[c][g]=s[g][c]=-3;
s[c][t]=s[t][c]=-2;
s[c][1]=s[1][c]=-4;
s[g][t]=s[t][g]=-2;
s[1][g]=s[g][1]=-2;
s[1][t]=s[t][1]=-1;
}//这代码,太不美观了
int main()
{
int cas,L1,L2;
char s1[101],s2[101];
init();
scanf("%d",&cas);
while(cas--)
{
scanf("%d %s",&L1,s1);
scanf("%d %s",&L2,s2);
memset(dp,0,sizeof(dp));
dp[0][0]=0;
for(int j=1;j<=L2;j++)
dp[0][j]=dp[0][j-1]+s[1][s2[j-1]-'A'];
for(int i=1;i<=L1;i++)
dp[i][0]=dp[i-1][0]+s[s1[i-1]-'A'][1];
for(int i=1;i<=L1;i++)
{
for(int j=1;j<=L2;j++)
{
dp[i][j]=dp[i-1][j-1]+s[s1[i-1]-'A'][s2[j-1]-'A'];
if(dp[i][j]<dp[i-1][j]+s[s1[i-1]-'A'][1])
dp[i][j]=dp[i-1][j]+s[s1[i-1]-'A'][1];
if(dp[i][j]<dp[i][j-1]+s[1][s2[j-1]-'A'])
dp[i][j]=dp[i][j-1]+s[1][s2[j-1]-'A'];
}
}
printf("%d\n",dp[L1][L2]);
}
return 0;
}