这题方程很好想,只是我觉得不太好证明最优子结构。。。智商捉急。。。
dp[i][j]=max(dp[i-1][j]+mt[s1[i]]['-'],dp[i][j-1]+mt[s2[j]['-'],dp[i-1][j-1]+mt[s1[i]][s2[j]]);
Discuss里面有很好很强大的证明。。。
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
int mt[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 conv(char tc)
{
switch (tc)
{
case 'A':
return 0;
case 'C':
return 1;
case 'G':
return 2;
case 'T':
return 3;
}
}
int main()
{
int i,j,prob,l1,l2,s1[110],s2[110],dp[110][100],t;
char str[110];
scanf("%d",&prob);
while (prob--)
{
scanf("%d",&l1);
scanf("%s",str);
for (i=0; i<l1; i++)
{
s1[i+1]=conv(str[i]);
}
scanf("%d",&l2);
scanf("%s",str);
for (i=0; i<l2; i++)
{
s2[i+1]=conv(str[i]);
}
dp[0][0]=0;
for (i=1; i<=l1; i++)
{
dp[i][0]=dp[i-1][0]+mt[s1[i]][4];
}
for (i=1; i<=l2; i++)
{
dp[0][i]=dp[0][i-1]+mt[s2[i]][4];
}
for (i=1; i<=l1; i++)
{
for (j=1; j<=l2; j++)
{
t=dp[i-1][j]+mt[s1[i]][4];
dp[i][j]=t;
t=dp[i][j-1]+mt[s2[j]][4];
dp[i][j]=dp[i][j]>t?dp[i][j]:t;
t=dp[i-1][j-1]+mt[s1[i]][s2[j]];
dp[i][j]=dp[i][j]>t?dp[i][j]:t;
}
}
printf("%d\n",dp[l1][l2]);
}
}