题目分析:
•这一题是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; }