题目描述 
小 A 最近一直在找自己的爸爸,用什么办法呢,就是 DNA 比对。 
小 A 有一套自己的 DNA 序列比较方法,其最终目标是最大化两个 DNA 序列的相似程度,具体步骤如下: 
1. 给出两个 DNA 序列,第一个长度为
2. 在两个序列的任意位置插入任意多的空格,使得两个字符串长度相同。 
3. 逐位进行匹配,如果两个序列相同位置上的字符都不是空格,假设第一个是
那么最终两个序列的相似程度就是所有的
现在小 A 通过某种奥妙重重的方式得到了小 B 的 DNA 序列中的一段,他想请你帮他算一下小 A 的 DNA 序列和小 B 的 DNA 序列的最大相似程度。
输入格式 
输入第
输入第
接下来
最后一行两个用空格隔开的正整数
输出格式 
输出共一行,表示两个序列的最大相似程度。
样例输入 
ATGG 
ATCC 
5 -4 -4 -4 
-4 5 -4 -4 
-4 -4 5 -4 
-4 -4 -4 5 
2 1
样例输出 
4
样例解释 
首先,将序列补成如下形式(-代表空格) 
A T G G - - 
A T - - C C 
然后所有
数据范围与提示 
对于所有测试点,有
| 测试点编号 | 特殊约定 | |
|---|---|---|
| 1 | 无特殊要求 | |
| 2 | 无特殊要求 | |
| 3 | 无特殊要求 | |
| 4 | 无特殊要求 | |
| 5 | 序列中只包含一种字符 | |
| 6 | 无特殊要求 | |
| 7 | 无特殊要求 | |
| 8 | 无特殊要求 | |
| 9 | 无特殊要求 | |
| 10 | 无特殊要求 | 
来自 CodePlus 2017 11 月赛,清华大学计算机科学与技术系学生算法与竞赛协会 荣誉出品。 
Credit:idea/邢健开 命题/邢健开 验题/陈宇 
Git Repo:https://git.thusaac.org/publish/CodePlus201711 
感谢腾讯公司对此次比赛的支持。
思路 
直接dp,方程太长,看代码好了。
代码
#include <cstdio>
#include <algorithm>
#include <cstring>
const int maxn=3000;
const int inf=1000000000;
int f[maxn+10][maxn+10][2][2];
//f[i][j][k][l]代表A序列匹配到了i位,B序列匹配到了j位,k代表A序列末尾是否有空格,l代表B序列是否有空格
char s[maxn+10],t[maxn+10];
int a[maxn+10],b[maxn+10],w[4][4],lena,lenb,x,y;
int main()
{
  scanf("%s%s",s+1,t+1);
  lena=strlen(s+1);
  lenb=strlen(t+1);
  for(register int i=1; i<=lena; ++i)
    {
      if(s[i]=='A')
        {
          a[i]=0;
        }
      else if(s[i]=='T')
        {
          a[i]=1;
        }
      else if(s[i]=='G')
        {
          a[i]=2;
        }
      else if(s[i]=='C')
        {
          a[i]=3;
        }
    }
  for(register int i=1; i<=lenb; ++i)
    {
      if(t[i]=='A')
        {
          b[i]=0;
        }
      else if(t[i]=='T')
        {
          b[i]=1;
        }
      else if(t[i]=='G')
        {
          b[i]=2;
        }
      else if(t[i]=='C')
        {
          b[i]=3;
        }
    }
  for(register int i=0; i<4; ++i)
    {
      for(register int j=0; j<4; ++j)
        {
          scanf("%d",&w[i][j]);
        }
    }
  scanf("%d%d",&x,&y);
  f[0][0][0][0]=0;
  f[0][0][0][1]=-inf;
  f[0][0][1][0]=-inf;
  for(register int i=1; i<=lena; ++i)
    {
      f[i][0][0][1]=-x-y*(i-1);
      f[i][0][1][0]=f[i][0][0][0]=-inf;
    }
  for(register int i=1; i<=lenb; ++i)
    {
      f[0][i][1][0]=-x-y*(i-1);
      f[0][i][0][1]=f[0][i][0][0]=-inf;
    }
  //上面赋初值,下面dp
  for(register int i=1; i<=lena; ++i)
    {
      for(register int j=1; j<=lenb; ++j)
        {
          f[i][j][0][0]=std::max(f[i-1][j-1][0][0],std::max(f[i-1][j-1][0][1],f[i-1][j-1][1][0]))+w[a[i]][b[j]];
          f[i][j][0][1]=std::max(f[i-1][j][0][0]-x,std::max(f[i-1][j][1][0]-x,f[i-1][j][0][1]-y));
          f[i][j][1][0]=std::max(f[i][j-1][0][0]-x,std::max(f[i][j-1][0][1]-x,f[i][j-1][1][0]-y));
        }
    }
  printf("%d\n",std::max(f[lena][lenb][0][0],std::max(f[lena][lenb][1][0],f[lena][lenb][0][1])));
  return 0;
} 
                    
                 
 
                
            
         浙公网安备 33010602011771号
浙公网安备 33010602011771号