正文

Zju 1027 Human Gene Functions2006-08-14 18:05:00

【评论】 【打印】 【字体: 】 本文链接:http://blog.pfan.cn/cruxd/17566.html

分享到:

2021057 2006-08-14 17:39:09 Accepted 1027 C++ 00:00.01 428K St.Crux 两个字符串si和sk,每个字符匹配都有一个权值,要求他们的最大匹配权值。 很久以前在论坛上看过介绍,说和求最长子序列十分类似,因此很快就联想到了dp:) 事实上,这个题和LCS......确实很相似。同样是用一个二维数组来表示si的前i个数与sk的前k个数(字符)匹配的最大值,同样在f(n, m)处得解。不同的是LCs求的是最大长度,而这个求的是最大值。 所以用从下向上递推的思想分析。比如si=AT,sk=TA。当A和T匹配后,显然有一种情况:f(2, 2) = f(1,1) + a[2][2]; 那么移一位如何?即把si的T移动到TA的后面,使A和TA匹配,得f(2, 2) = f(1, 2) + T与-的匹配值。同理可得其他情况,在这些情况中取最大值即可。 #include <cstdio>#include <string> int a[5][5] = { {5, -1, -2, -1, -3}, {-1, 5, -2, -3, -4}, {-2, -3, 5, -2, -2}, {-1, -2, -2, 5, -1}, {-3, -4, -2, -1, 0} }, b[101][101], s0[101], s1[101];int n, m, t, ans; int mx(int a, int b, int c){ if(a >= b && a >= c)  return a; if(b >= a && b >= c)  return b; if(c >= a && c >= b)  return c; else  return -99999999;} void read(){ char tc; int k; scanf("%d ", &n); for(k = 0; k < n; k ++) {    scanf("%c", &tc);  if(tc == 'A') s0[k] = 0;  if(tc == 'C') s0[k] = 1;  if(tc == 'G') s0[k] = 2;  if(tc == 'T') s0[k] = 3; } scanf("%d ", &m); for(k = 0; k < m; k ++) {  scanf("%c", &tc);  if(tc == 'A') s1[k] = 0;  if(tc == 'C') s1[k] = 1;  if(tc == 'G') s1[k] = 2;  if(tc == 'T') s1[k] = 3; }} void init(){ memset(b, 0, sizeof(b)); int i, sum = 0; for(i = 1; i <= n; i ++) {  sum += a[s0[i - 1]][4];  b[i][0] = sum; } sum = 0; for(i = 1; i <= m; i ++) {  sum += a[s1[i - 1]][4];  b[0][i] = sum; } ans = -99999999;} void dp(){ int i, k; for(i = 1; i <= n; i ++) {  for(k = 1; k <= m; k ++)  {   int ta = b[i - 1][k - 1] + a[s0[i - 1]][s1[k - 1]];   int tb = b[i][k - 1] + a[4][s1[k - 1]];   int tc = b[i - 1][k] + a[s0[i - 1]][4];   b[i][k] = mx(ta, tb, tc);  } } ans = b[n][m];} void ps(){ int i; for(i = 0; i < n; i ++) {  printf("%d ", s0[i]); } printf("\n"); for(i = 0; i < m; i ++) {  printf("%d ", s1[i]); } printf("\n");} void pb(){ int i, k; for(i = 0; i <= n; i ++) {  for(k = 0; k  <= m; k ++)  {   printf("%d ", b[i][k]);  }  printf("\n"); } printf("\n");}  int main(){ //freopen("in.txt", "r", stdin); scanf("%d", &t); int i; for(i = 0; i < t; i ++) {  read();  init();    dp();  //pb();  printf("%d\n", ans); } return 0;}      

阅读(4978) | 评论(2)


版权声明:编程爱好者网站为此博客服务提供商,如本文牵涉到版权问题,编程爱好者网站不承担相关责任,如有版权问题请直接与本文作者联系解决。谢谢!

评论

loading...
您需要登录后才能评论,请 登录 或者 注册