LCS的变形而已
注意LCS的子串可以是离散的,不必连续,用动态规划
设dp[i][j]为取s1第i个字符,s2第j个字符时的最大分值
则决定dp为最优的情况有三种(score[][]为s1[i]和s2[j]两符号的分数):
1、 s1取第i个字母,s2取“ - ”: dp[i-1][j]+score[ s1[i-1] ]['-'];
2、 s1取“ - ”,s2取第j个字母:dp[i][j-1]+score['-'][ s2[j-1] ];
3、 s1取第i个字母,s2取第j个字母:dp[i-1][j-1]+score[ s1[i-1] ][ s2[j-1] ];
即dp[i][j]=max( dp[i-1][j]+score[ s1[i-1] ]['-'],
dp[i][j-1]+score['-'][ s2[j-1] ],
dp[i-1][j-1]+score[ s1[i-1] ][ s2[j-1] ] );
注意初始化
不仅仅只有
dp[0][0] = 0
也不仅仅是
dp[0][0] = 0
dp[1][0] = score[ s1[i-1] ]['-']
dp[0][1] = score['-'][ s2[j-1] ]
必须全面考虑到所有情况,
当i=j=0时,dp[i][j]=0
当i=0时,dp[0,j] = dp[0][j-1] + score['-'][ s2[j-1] ]
当j=0时,dp[i,0] = dp[i-1][0] + score[ s1[i-1] ]['-']
代码:
#include <iostream>
#include <stdlib.h>
#define maxN 105
using namespace std ;
char x[maxN];
char y[maxN];
int matrix[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 getInt(char c)
{
switch(c)
{
case 'A':
return 0;
case 'C':
return 1;
case 'G':
return 2;
case 'T':
return 3;
default:
return 4;
}
}
int max(int a,int b,int c)
{
if (a>b)
if (a>c)
return a;
else
return c;
else
if (b>c)
return b;
else
return c;
}
int main()
{
int t;
int m,n;
cin>>t;
while(t--)
{
cin>>n;
for (int i=1;i<=n;i++)
cin>>x[i];
cin>>m;
for (int i=1;i<=m;i++)
cin>>y[i];
int **D=new int*[n+1];
for (int i=0;i<=n;i++)
D[i]=new int[m+1];
D[0][0]=0;
for(int i= 1; i<= n; i++) D[i][0] =matrix[getInt(x[i])][4]+D[i-1][0];
for(int j = 1; j <= m; j++) D[0][j] =matrix[4][getInt(y[j])]+D[0][j-1];
for(int i= 1; i<= n; i++) {
for(int j = 1; j <= m; j++) {
D[i][j]=max(D[i-1][j]+matrix[getInt(x[i])][4],
D[i][j-1]+matrix[4][getInt(y[j])],
D[i-1][j-1]+matrix[getInt(x[i])][getInt(y[j])]);
// cout<<i<<","<<j<<":"<<D[i][j]<<endl;
// cout<<getInt(x[i])<<"/"<<getInt(y[j])<<endl;
}
}
cout<<D[n][m]<<endl;
for (int i=0;i<=n;i++)
delete [] D[i];
delete [] D;
}
return 0;
}