/**
观察题目给出的一个最优解:
AGTGATG
-GTTA-G
将其从某一处切开,如果左边部分的分值不是最大,那么将其进行调整,
使其分值变大,则整个解分值变大,与已知的最优矛盾。
所以左边部分的分值必是最大。同理,右边也是。
可见满足最优子结构的性质。考虑使用DP:
设两个DNA序列分别为s1,s2,长度分别为len1,len2,score为分值表。
f[i,j]表示子串s1[1..i]和s2[1..j]的分值。考虑一个f[i,j],我们有:
1.s1取第i个字母,s2取“-”:f[i-1,j] + score[s1[i],'-']
2.s1取“-”,s2取第j个字母:f[i,j-1] + score['-',s2[j]]
3.s1取第i个字母,s2取第j个字母:f[i-1,j-1] + score[s1[i],s2[j]]
即f[i,j] = max(f[i-1,j] + score[s1[i],'-'], f[i,j-1] + score['-',
s2[j]], f[i-1,j-1] + score[s1[i],s2[j]]);
然后考虑边界条件,这道题为i或j为0的情况。
当i=j=0时,即为f[0,0],这是在计算f[1,1]时用到的,
根据f[1,1] = f[0,0] + score[s1[i], s2[j]],明显有f[0,0] = 0。
当i=0时,即为f[0,1..len2],有了f[0,0],可以用f[0,j] = f[0,j-1] + table['-',s2[j]]来计算。
当j=0时,即为f[1..len1,0],有了f[0,0],可以用f[i,0] = f[i-1,0] + table[s1[i],'-']来计算。
至于计算顺序,只要保证计算f[i,j]的时候,
使用到的f[i-1,j],f[i,j-1],f[i-1,j-1]都计算出来了就行了。
所谓划分阶段也就是为了达到这个目的。这样我们使用一个二重循环就可以了。
*/
/**
以 AGTGATG 和 GTTAG 为例
A G T G A T G
0 2 3 2 0 3 2
G T T A G
2 3 3 0 2
0 1 2 3 4 5
-------------------------------------------------
- -- --- ---- -----
G GT GTT GTTA GTTAG
0 0 -2 -3 -4 -7 -9
-------------------------------------------------
A A -A --A ---A ---A-
- G GT GTT GTTA GTTAG
1 -3 -2 -3 -4 1 -1
-------------------------------------------------
AG AG AG- AG-- ---A- ---AG
-- -G -GT -GTT GTTAG GTTAG
2 -5 2 1 0 -1 6
-------------------------------------------------
AGT AGT AGT AGT- AGT-- ---AGT
--- -G- -GT -GTT -GTTA GTTAG-
3 -6 1 7 6 3 5
-------------------------------------------------
AGTG AGTG AGTG AGTG AGT-G AGT--G
---- -G-T -GT- -GTT -GTTA -GTTAG
4 -8 -1 5 5 4 8
-------------------------------------------------
AGTGA AGTGA AGTGA AGTGA AGTGA AGTGA-
----- -G-T- -GT-- -GT-T -GTTA -GTTAG
5 -11 -4 2 4 10 8
-------------------------------------------------
AGTGAT AGTGAT AGTGAT AGTGAT AGTGAT AGTGAT
------ -G-T-- -G-T-T -GT--T -GTTA- -GTTAG
6 -12 -5 1 7 9 8
-------------------------------------------------
AGTGATG AGTGATG AGTGATG AGTGATG AGTGATG AGTGATG
------- ------G -G-T-T- -GT--T- -GTTA-- -GTTA-G
7 -14 -7 -1 5 7 14
-------------------------------------------------
*/
#include<stdio.h>
void change(char s[],int d[],int len){
int i;
for(i=0;i<len;i++){
if(s[i]=='A')d[i]=0;
else if(s[i]=='C')d[i]=1;
else if(s[i]=='G')d[i]=2;
else if(s[i]=='T')d[i]=3;
}
}
int max(int a,int b,int c){
int i;
i=a>b?a:b;
return i>c?i:c;
}
int main(){
int score[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 f[201][201],d1[101],d2[101];
int test,len1,len2,i,j;
char s1[101],s2[101];
int a,b,c;
//freopen("in.txt","r",stdin);
scanf("%d",&test);
while(test--){
scanf("%d%s",&len1,s1);
change(s1,d1,len1);
scanf("%d%s",&len2,s2);
change(s2,d2,len2);
for(i=0;i<=len1;i++){
for(j=0;j<=len2;j++){
if(i==0&&j){
f[0][j]=f[0][j-1]+score[4][d2[j-1]];
}
else if(i==0&&j==0){
f[0][0]=0;
}
else if(i&&j==0){
f[i][0]=f[i-1][0]+score[d1[i-1]][4];
}
else{
a=f[i-1][j]+score[d1[i-1]][4];
b=f[i][j-1]+score[4][d2[j-1]];
c=f[i-1][j-1]+score[d1[i-1]][d2[j-1]];
f[i][j]=max(a,b,c);
}
}
}
printf("%d\n",f[len1][len2]);
}
}
北大ACM poj1080 Human Gene Functions
最新推荐文章于 2023-08-29 20:02:38 发布