您的位置:首页 > 其它

poj 1080 Human Gene Functions

2013-08-29 18:42 393 查看
 

这是一道比较经典的DP,两串基因序列包含A、C、G、T,每两个字母间的匹配

产生一个相似值,求基因序列(字符串)匹配的最大值。 

这题有点像求最长公共子序列。只不过把求最大长度改成了求最大的匹配值。用二

组opt[i][j]记录字符串a中的前i 个字符与字符串b中的前j 个字符匹配所产生的最大值

如已知AG和GT的最大匹配值,AGT和GT的最大匹配值,AG和GTT的最大匹配

求AGT和GTT的最大匹配值,这个值是AG和GT的最大匹配值加上T 和T的匹配

AGT和GT的最大匹配值加上T 和-的匹配值,AG和GTT的最大匹配值加上-和T的

值中的最大值,所以状态转移方程: 

opt[i][j]  =max(opt[i-1][j-1]+table(b[i-1],a[j-1]),opt[i][j-1]+table('-',a[j-1]),opt[i-1][j]+table('-',b[i-1])); 

#include <iostream>
#include <stdio.h>
#include <algorithm>
#include <set>
#include <map>
#include <string>
using namespace std;
map < char,map<char,int> > m;
void Init()
{
m['A']['C']=-1;m['C']['A']=-1;
m['A']['G']=-2;m['G']['A']=-2;
m['A']['T']=-1;m['T']['A']=-1;
m['A']['-']=-3;m['-']['A']=-3;
m['C']['G']=-3;m['G']['C']=-3;
m['C']['T']=-2;m['T']['C']=-2;
m['C']['-']=-4;m['-']['C']=-4;
m['G']['T']=-2;m['T']['G']=-2;
m['G']['-']=-2;m['-']['G']=-2;
m['T']['-']=-1;m['-']['T']=-1;
m['A']['A']=m['G']['G']=m['C']['C']=m['T']['T']=5;
}
int main()
{
Init();
string a,b;
int la,lb;
int n;
int w[200][200];
scanf("%d",&n);
while(n--)
{
scanf("%d",&la);
cin>>a;
scanf("%d",&lb);
cin>>b;
for(int i=la;i>0;i--)
a[i]=a[i-1];
for(int i=lb;i>0;i--)
b[i]=b[i-1];
w[0][0]=0;
//特别注意边界值的初始化
for(int i=1;i<=la;i++)
w[i][0]=w[i-1][0]+m[a[i]]['-'];
for(int i=1;i<=lb;i++)
w[0][i]=w[0][i-1]+m['-'][b[i]];
int t1,t2,t3;
for(int i=1;i<=la;i++)
{
for(int j=1;j<=lb;j++)
{
t1=w[i-1][j-1]+m[a[i]][b[j]];
t2=w[i][j-1] +m['-'][b[j]];
t3=w[i-1][j] +m[a[i]]['-'];
w[i][j]=max(max(t1,t2),t3);
}
}
printf("%d\n",w[la][lb]);
}
return 0;
}

/*
4 AAAA
1 A
*/
/*
起初认为可以直接拿小的串陪大的串 小串加-号就行 实际上是错的
反例
AT
TA
按我的算法 答案是-2
正确应该是 -AT
TA- 答案是3

*/
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: