题目:http://poj.org/problem?id=1080
两个串,求最大匹配度,可以插入‘-’,比如: AGTGATG GTTAG
有2种匹配方案:
(1)AGTGAT-G
-GT--TAG
(2)AGTGATG
-GTTA-G
a,b串,d[i][j] 表示a[0]~a[i-1]和b[0]~b[j-1]的匹配度。
a[i]和b[j]有三种匹配方案:
(1)a[i]~b[j];(2)a[i]~'-';(3)'-'~b[j]
于是有状态转移方程:
d[i][j] =max(
d[i-1][j-1]+f(a[i-1],b[j-1]),
d[i-1][j]+f(a[i-1],'-');
d[i][j-1]+f('-',b[j-1])
)
再注意下边界处理,就OK了。
代码:
#include <stdio.h>
#include <string.h>
char a[101],b[101];
int map[101][101];
int chart[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,10}};
int idx(char x);
int max(int a,int b);
int main()
{
int T,i,j,ans,alen,blen,tmp;
scanf("%d",&T);
do
{
scanf("%d%s",&alen,a);
scanf("%d%s",&blen,b);
memset(map,0,sizeof(map));
for(i = 1 ; i <= alen ; ++i)
map[i][0] = map[i-1][0] + chart[idx(a[i-1])][idx('-')] ;
for(i = 1 ; i <= blen ; ++i)
map[0][i] = map[0][i-1] + chart[idx('-')][idx(b[i-1])];
for(i = 1 ; i <= alen ; ++i)
for(j = 1 ; j <= blen ; ++j)
{
tmp = max(map[i-1][j-1]+chart[idx(a[i-1])][idx(b[j-1])],
map[i-1][j]+chart[idx(a[i-1])][idx('-')]) ;
map[i][j] =max(tmp,map[i][j-1]+chart[idx('-')][idx(b[j-1])]);
}
printf("%d\n",map[alen][blen]);
}while(--T);
system("pause");
return 0;
}
int idx(char x)
{
int ans;
switch(x)
{
case 'A':ans = 0;break;
case 'C':ans = 1;break;
case 'G':ans = 2;break;
case 'T':ans = 3;break;
default: ans = 4;break;
};
return ans;
}
int max(int a,int b)
{
return a>b? a:b;
}