您的位置:首页 > 其它

POJ 1080 Human Gene Functions(dp)

2014-11-07 21:04 507 查看
题意:给定两个字符串,求它们对齐匹配的最大值

要求:可以两个字符匹配,也可以一个字符和‘-’匹配,

但是不能两个‘-’匹配,例如:

AGTGATG

GTTAG

这两个字符串可以看成是

AGTGATG

-GTTA-G

也可以看成是

AGTGAT-G

-GT--TAG

分析:这是一个变形的最长公共子序列,最优解:

1.取字符i-1和j-1的时候dp[i][j]=dp[i-1][j-1]+a[s1[i-1]][s2[j-1]];
2.取字符i-1,不取j-1的时候dp[i][j]=dp[i-1][j]+a[s1[i-1]]['-'];
3.取字符j-1,不取i-1的时候dp[i][j]=dp[i][j-1]+a['-'][s2[j-1]];

而dp[i][j]取这三个值的最大值就可以了

当然初始化的时候dp[0][0]=0;
但是因为每个字符都要和一个字符对齐,当然不包括'-'和'-'两个字符对齐
所以当dp[0][i]的时候就代表s2[i-1]与'-'对齐,

所以dp[0][j]=dp[0][j-1]+a['-'][s2[j-1]];
同理dp[i][0]=dp[i-1][0]+a[s1[i-1]]['-'];

#include<stdio.h>
char s1[110],s2[110];
int dp[110][110];
int n1,n2;
int a[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 max(int a,int b,int c)
{
int maxn=a;
if(b>maxn)
maxn=b;
if(c>maxn)
maxn=c;
return maxn;
}
int get(char ch)
{
if(ch=='A')
return 0;
if(ch=='C')
return 1;
if(ch=='G')
return 2;
if(ch=='T')
return 3;
if(ch=='-')
return 4;
}
void dpdp()
{
dp[0][0]=0;
int x,y,z;
int i,j;
for(i=1; i<=n1; i++)
dp[i][0]=dp[i-1][0]+a[get(s1[i-1])][get('-')];
for(j=1; j<=n2; j++)
dp[0][j]=dp[0][j-1]+a[get('-')][get(s2[j-1])];
for(i=1; i<=n1; i++)
{
for(j=1; j<=n2; j++)
{
x=dp[i-1][j-1]+a[get(s1[i-1])][get(s2[j-1])];
y=dp[i-1][j]+a[get(s1[i-1])][get('-')];
z=dp[i][j-1]+a[get('-')][get(s2[j-1])];
dp[i][j]=max(x,y,z);
}
}
return ;
}
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
scanf("%d%s%d%s",&n1,s1,&n2,s2);
dpdp();
printf("%d\n",dp[n1][n2]);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: