您的位置:首页 > 其它

POJ 1080 && HDU 1080 Human Gene Functions(dp)

2015-08-23 13:55 525 查看
Description

给定两组DNA序列,要你求出它们的最大相似度

每个字母与其他字母或自身和空格对应都有一个打分,求在这两个字符串中插入空格,让这两个字符串的匹配分数最大



Input

T组用例,每组用例两个DNA长度(不超过100)及其序列

Output

对于每组用例,输出两个DNA序列的最大匹配分数

Sample Input

2

7 AGTGATG

5 GTTAG

7 AGCTATT

9 AGCTTTAAA

Sample Output

14

21

Solution

设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] ] );

注意初始化,必须全面考虑到所有情况,

当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] ][‘-‘]

Code

#include<cstdio>
#include<iostream>
using namespace std;
#define INF (1<<29)
#define maxn -5
#define Max(a,b) (a>b?a:b)
int score['T'+1]['T'+1];//积分表
void initial(void)//打表
{
score['A']['A']=5;
score['C']['C']=5;
score['G']['G']=5;
score['T']['T']=5;
score['-']['-']=INF;
score['A']['C']=score['C']['A']=-1;
score['A']['G']=score['G']['A']=-2;
score['A']['T']=score['T']['A']=-1;
score['A']['-']=score['-']['A']=-3;
score['C']['G']=score['G']['C']=-3;
score['C']['T']=score['T']['C']=-2;
score['C']['-']=score['-']['C']=-4;
score['G']['T']=score['T']['G']=-2;
score['G']['-']=score['-']['G']=-2;
score['T']['-']=score['-']['T']=-1;
return;
}
int main()
{
initial();
int T;
cin>>T;
while(T--)
{
int i,j,len1,len2;
cin>>len1;
char*s1=new char[len1+1];
cin>>s1;
cin>>len2;
char*s2=new char[len2+1];
cin>>s2;
int**dp=new int*[len1+1];//申请二维动态数组,第一维
dp[0]=new int[len2+1];
dp[0][0]=0;//初始化
for(i=1;i<=len1;i++)//初始化
{
dp[i]=new int[len2+1];//申请二维动态数组,第二维
dp[i][0]=dp[i-1][0]+score[s1[i-1]]['-'];//注意下标,dp数组是从1开始,s1和s2都是从0开始
}
for(i=1;i<=len2;i++)//初始化
dp[0][i]=dp[0][i-1]+score['-'][s2[i-1]];//注意下标,dp数组是从1开始,s1和s2都是从0开始
for(i=1;i<=len1;i++)
for(j=1;j<=len2;j++)
{
int temp1=dp[i-1][j]+score[s1[i-1]]['-'];
int temp2=dp[i][j-1]+score['-'][s2[j-1]];
int temp3=dp[i-1][j-1]+score[s1[i-1]][s2[j-1]];
dp[i][j]=Max(temp1,(Max(temp2,temp3)));
}
cout<<dp[len1][len2]<<endl;
delete[] dp;//释放动态数组
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: