hdu 1080 pku1080 基因序列匹配问题

题目分析:

这一题是LCS,只是一个变形而已,有三种情况 dist[ ][ ]为两符号所得的分数):
1s1取第i个字母,s2 - dp[i][j] = dp[i-1,j] + dist[s1[i],'-'];
2  s1 - s2取第j个字母:dp[i][j] = dp[i,j-1] + dist['-',s2[j]];
3  s1取第i个字母,s2取第j个字母:dp[i][j] = dp[i-1,j-1] + dist[s1[i],s2[j]]
 dp[i,j]=max( dp[i-1,j] + dist[s1[i],'-'], dp[i,j-1]+dist['-',s2[j]], dp[i-1,j-1]+dist[s1[i],s2[j]]);
值得注意的是边界的问题,如何去初始化:
考虑边界条件,这道题为ij0的情况。当i=j=0时,即为dp[0,0],这是在计算dp[1,1]时用到的,根据dp[1,1]=dp[0,0] + dist[s1[i], s2[j]]明显有dp[0,0] = 0
i=0时,dp[0,j] = dp[0,j-1] + dist['-',s2[j]]来计
j=0时,dp[i,0] = dp[i-1,0] + dist[s1[i],'-']来计
#include<iostream>
#include<string>
#include<algorithm>
using namespace std;
int s[20][20];
int dp[101][101];
void init()
{
	int a=0,c=2,g=6,t=19;
	s[a][a]=s[c][c]=s[g][g]=s[t][t]=5;
	s[a][c]=s[c][a]=-1;
	s[a][g]=s[g][a]=-2;
	s[a][t]=s[t][a]=-1;
	s[a][1]=s[1][a]=-3;
	s[c][g]=s[g][c]=-3;
	s[c][t]=s[t][c]=-2;
	s[c][1]=s[1][c]=-4;
	s[g][t]=s[t][g]=-2;
	s[1][g]=s[g][1]=-2;
	s[1][t]=s[t][1]=-1;
}//这代码,太不美观了
int main()
{
	int cas,L1,L2;
	char s1[101],s2[101];
	init();
	scanf("%d",&cas);
	while(cas--)
	{
		scanf("%d %s",&L1,s1);
		scanf("%d %s",&L2,s2);
		memset(dp,0,sizeof(dp));
		dp[0][0]=0;
		for(int j=1;j<=L2;j++)
			dp[0][j]=dp[0][j-1]+s[1][s2[j-1]-'A'];
		for(int i=1;i<=L1;i++)
			dp[i][0]=dp[i-1][0]+s[s1[i-1]-'A'][1];
		for(int i=1;i<=L1;i++)
		{
			for(int j=1;j<=L2;j++)
			{
			   dp[i][j]=dp[i-1][j-1]+s[s1[i-1]-'A'][s2[j-1]-'A'];
				if(dp[i][j]<dp[i-1][j]+s[s1[i-1]-'A'][1])
					dp[i][j]=dp[i-1][j]+s[s1[i-1]-'A'][1];
				if(dp[i][j]<dp[i][j-1]+s[1][s2[j-1]-'A'])
					dp[i][j]=dp[i][j-1]+s[1][s2[j-1]-'A'];
			}
		}
		printf("%d\n",dp[L1][L2]);
	}
	return 0;
}
	

  


原文地址:https://www.cnblogs.com/nanke/p/2147454.html