首页 > 代码库 > POJ 1080 Human Gene Functions(求两字符串相似度:LCS变形)
POJ 1080 Human Gene Functions(求两字符串相似度:LCS变形)
POJ 1080 Human Gene Functions(求两字符串相似度:LCS变形)
http://poj.org/problem?id=1080
题意: HDU1080
给你两个由字符A,C,G,T构造的字符串s1和s2, 现在你可以在这两个字符串中插入空格, 使得两串长相等(但是不能使得s1的空格对应s2的空格位置). 然后给你s1的特定字符对应s2中特定字符所能获得的分数矩阵:
问你最后两个字符串所能获得的最大分数是多少?
分析:
本题很类似于求字符串最短编辑距离或者求字符串LCS的问题, 都是从两个字符串的最后一个字符入手.
令dp[i][j]==x表示原始串s1的前i个字符和s2的前j个字符通过插入空格能获得的最大分数为x.
初始化:dp[0][0]=0, dp[i][0]和dp[0][i]为s1和s2前i个字符对应空格的分数.
状态转移:
dp[i][j] = max( dp[i-1][j-1]+[s1[i]和s2[j]对应的分数] , dp[i-1][j]+[s1[i]和空格对应的分数] , dp[i][j-1]+[空格和s2[j]对应的分数] )
上述第一个表示s1和s2最后一个位置都加空格, 所以是原本的字符对比获取分数.
第2个表示s1的最后一个字符和s2的末尾添加空格比较获取分数.
第3个表示s1的末尾添加空格来和s2对比.
最终所求:dp[len(s1)][len(s2)].
AC代码:
#include<cstdio> #include<algorithm> #include<cstring> using namespace std; const int maxn=100+5; int n,m; int dp[maxn][maxn]; char s1[maxn],s2[maxn]; int score[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 id[500]; int main() { id['A']=0;//A字符对应0编号 id['C']=1; id['G']=2; id['T']=3; id[' ']=4; int T; scanf("%d",&T); while(T--) { scanf("%d%s",&n,s1); scanf("%d%s",&m,s2); //初始化 dp[0][0]=0; for(int i=1;i<=m;i++) dp[0][i]=dp[0][i-1]+score[id[' ']][id[s2[i-1]]]; for(int i=1;i<=n;i++) dp[i][0]=dp[i-1][0]+score[id[' ']][id[s1[i-1]]]; //递推过程 for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) { int id1=id[s1[i-1]], id2=id[s2[j-1]]; dp[i][j]=dp[i-1][j-1]+score[id1][id2]; int tmp=max( dp[i-1][j]+score[id1][4] , dp[i][j-1]+score[4][id2] ); dp[i][j]=max(dp[i][j], tmp ); } printf("%d\n",dp[n][m]); } return 0; }
POJ 1080 Human Gene Functions(求两字符串相似度:LCS变形)