POJ1080 Human Gene Functions

           本题的大意是,人类的基因组成包括4种碱基:A,C,G,T构成,现在要根据相应的矩阵分析给出的两个DNA的相似度。在计算的过程中,由于两个DNA长度可能不等,需要插入“-”来填补,需要解决的问题就是如何插入“-”使得两个DNA的相似度最高。

        做到这题时,正好在编程之美上看到了一题类似的题,根据对那题的理解马上勾勒出了程序的大体框架:假设两个DNA分别为A,B。对于每个碱基,都有三种情况:在A中插入“-”,在B中插入“-”,以及A,B中均不插入。根据这样的分析,可以定义一个状态:d(i,j),表示的是A中处理位置为i,B中处理位置为j能取得的最大相似度。不难求出三种情况下的状态转移方程。我用的是递归方法解决,需要注意一下边界问题,同时需要注意的是初始化不能初始化为-1,因为在计算过程中,有的相似度会是负数。


#include <stdio.h>
#include <string.h>


int scores[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
};
char A_query[102];
char B_query[102];
int Alen,Blen;
int d[102][102];

int max(int a,int b,int c);
int getscore(char a);

int main()
{
	int count,i,j;

	//freopen("test.txt","r",stdin);

	scanf("%d",&count);

	while(count--)
	{
		scanf("%d",&Alen);
		getchar();
		scanf("%s",A_query);
		scanf("%d",&Blen);
		getchar();
		scanf("%s",B_query);

		for(i=0;i<102;i++)
			for(j=0;j<102;j++)
				d[i][j]=-10000;
		printf("%d\n",search(0,0));
	}
	return 0;
}

int search(int A_index,int B_index)
{
	int len1,len2,len3;
	int total,i;

	total=0;
	if(d[A_index][B_index]>-10000)
		return d[A_index][B_index];
   if(A_index>=Alen)    //边界处理:某一DNA已到最后一个元素时,只能在后面添加"-"
   {
	   for(i=B_index;i<Blen;i++)
		   total+=scores[4][getscore(B_query[i])];

	   return total;
   }

   if(B_index>=Blen)
   {
	   for(i=A_index;i<Alen;i++)
		   total+=scores[getscore(A_query[i])][4];
	   return total;
   }

	len1=search(A_index+1,B_index)+scores[getscore(A_query[A_index])][4];
	len2=search(A_index+1,B_index+1)+scores[getscore(A_query[A_index])][getscore(B_query[B_index])];
	len3=search(A_index,B_index+1)+scores[4][getscore(B_query[B_index])];

	total=max(len1,len2,len3);
    d[A_index][B_index]=total;

	return d[A_index][B_index];
}
int getscore(char a)
{

	switch(a)
	{
	case 'A':return 0;
	case 'C':return 1;
	case 'G':return 2;
	case 'T':return 3;
	case '-':return 4;
	default:break;
	}
	return -1;
}

int max(int a,int b,int c)
{
	int temp;

	temp=a>b?a:b;

	return temp>c?temp:c;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值