poj1080

 /*
    这里我们定义一个数组a[len1][len2]  表示两个长度分别为len1,len2的最佳相似度
    其中  a[len1][len2]= max(a[len1-1][len2]+gene[s1[len1]]['-'],
    a[len1][len2-1]+gene['-'][s2[len2]],a[len1-1][len2-1]+gene[s1[len1]][s2[len2]])
   
    然后我们自底向上,可以这样写
    for(int i=1;i<=len1;i++)
     for(int j=1;j<=len2;j++)
      a[i][j]=max(a[i-1][j]+gene[my[s1[i]]][my['-']],
    a[i][j-1]+gene[my['-']][my[s2[j]]],a[i-1][j-1]+gene[my[s1[i]]][my[s2[j]]]);
   
    这里初始话的时候要注意,一开始要把他们的所有初始值,可以这样理解,
    因为第一次是s2和空格中的每一个字符匹配,保存这个值,第二次是将是
    空格和s2中的每一个字符匹配
   */
#include<iostream>
#include<string>
#include<fstream>
#include<map>
using namespace std;
int gene[][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 a[105][105];
map<char,int> my;
int len1,len2;
void init(map<char,int> &my)
{
  my.insert(make_pair('A',0));
  my.insert(make_pair('C',1));
  my.insert(make_pair('G',2));
  my.insert(make_pair('T',3));
  my.insert(make_pair('-',4));
}
int max(int a,int b,int c)
{
  return c>(a>b?a:b)?c:(a>b?a:b);
}
int main()
{
  //ifstream cin("poj1080.txt");
  init(my);
  string s1,s2;
  int nCase;
  cin>>nCase;
  while(nCase--)
  {
   cin>>len1>>s1;
   cin>>len2>>s2;
   s1="0"+s1;
   s2="0"+s2;  //下标从1开始
   memset(a,0,sizeof(a));
   for(int i=1;i<=len1;i++)
    a[i][0]=a[i-1][0]+gene[my[s1[i]]][4];
   for(int i=1;i<=len2;i++)
    a[0][i]=a[0][i-1]+gene[4][my[s2[i]]];
   for(int i=1;i<=len1;i++)
     for(int j=1;j<=len2;j++)
     {
  
      a[i][j]=max(a[i-1][j]+gene[my[s1[i]]][my['-']],
    a[i][j-1]+gene[my['-']][my[s2[j]]],a[i-1][j-1]+gene[my[s1[i]]][my[s2[j]]]);
     }
    cout<<a[len1][len2]<<endl; 
  }
  // system("pause");
   return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值