题目连接:http://acm.pku.edu.cn/JudgeOnline/problem?id=1080
1,opt[i][j]代表x中长度为i的前缀与y中长度为j的前缀的最优值
2,最优子结构:opt[i][j] = max(opt[i-1][j-1]+score[x[i]][y[j]],opt[i-1][j]+score[x[i]]['-'],opt[i][j-1]+score['-'][y[j]])
3,边界条件:opt[0][0] = 0,opt[0][i] = opt[0][i-1] + score['-'][y[i]],opt[i][0] = opt[i-1][0] + score[x[i]]['-']
WA了一次,边界值没有设置对,这里要求的是和,另外题目中'-'与'-'配对的得分应该是0,这是唯一一次能出现两者配对的情形要处理好,以后的通过最优子结构都限制住了,不能出现两个'-'相配对的情形。
#include <iostream>
using namespace std;
#define MAX 101
int Index(char ch)
{
switch(ch)
{
case 'A':
return 0;
case 'C':
return 1;
case 'G':
return 2;
case 'T':
return 3;
default:
return 4;
}
}
int main()
{
freopen("in.txt","r",stdin);
char g1[MAX],g2[MAX];
int t,i,j,len1,len2,score[5][5],opt[MAX][MAX];
score[0][0] = score[1][1] = score[2][2] = score[3][3] = 5;
score[4][4] = 0;
score[0][1] = -1,score[0][2] = -2,score[0][3] = -1,score[0][4] = -3;
score[1][2] = -3,score[1][3] = -2,score[1][4] = -4;
score[2][3] = -2,score[2][4] = -2;
score[3][4] = -1;
for(i = 1;i < 5;++i)
{
for(j = 0;j < i;++j)
score[i][j] = score[j][i];
}
g1[0] = g2[0] = '-';
cin >> t;
while(t--)
{
cin >> len1 >> g1 + 1;
cin >> len2 >> g2 + 1;
opt[0][0] = 0;
for(i = 1;i <= len1;++i)
opt[i][0] = score[Index(g1[i])][Index('-')] + opt[i-1][0];
for(j = 1;j <= len2;++j)
opt[0][j] = score[Index('-')][Index(g2[j])] + opt[0][j-1];
for(i = 1;i <= len1;++i)
{
for(j = 1;j <= len2;++j)
{
opt[i][j] = opt[i-1][j-1] + score[Index(g1[i])][Index(g2[j])];
if(opt[i][j] < opt[i-1][j] + score[Index(g1[i])][Index('-')])
opt[i][j] = opt[i-1][j] + score[Index(g1[i])][Index('-')];
if(opt[i][j] < opt[i][j-1] + score[Index('-')][Index(g2[j])])
opt[i][j] = opt[i][j-1] + score[Index('-')][Index(g2[j])];
}
}
#ifdef DEBUG
for(i = 0;i <= len1;++i)
{
for(j = 0;j <= len2;++j)
cout << opt[i][j] << ' ';
cout << endl;
}
#endif
cout << opt[len1][len2] << endl;
}
return 0;
}