LCS之poj1080

来源:互联网 发布:一加该网络 编辑:程序博客网 时间:2024/06/10 16:32

最长公共子序列(lcs)是dp的一块重要内容,求两段字符串的最大公共长度。

如下是模板代码:

               for (int i = 1; i <= str1.Length; i++)
                        for (int j = 1; j <= str2.Length; j++)
                         {
                                  //相等的情况
                                  if (str1[i - 1] == str2[j - 1])
                                             martix[i, j] = martix[i - 1, j - 1] + 1;
                                   else
                                   {
                                              //比较“左边”和“上边“,根据其max来填充
                                              if (martix[i - 1, j] >= martix[i, j - 1])
                                                          martix[i, j] = martix[i - 1, j];
                                               else
                                                          martix[i, j] = martix[i, j - 1];
                                    }
                           }


poj1080

题目大意:给定t的案例。一个案例给定两个字符串的长度,和字符串,只含有’A‘C’G‘T’-‘五个字符。并且给出每两个字符所代表的数字。要求在不改变最大长度的情况下,求出两个字符串匹配之后的最大数。(可在较短字符串内添加字符‘-’)


思路如下:

  字符串取str1[i] str2[j]时有以下三种情况
          1:str1[i]~~'-'         即temp1=map[i-1][j]+data[str1[i]]['-']
          2:  ‘-’~~str2[j]         即temp2=map[i][j-1]+data[str2[j]]['-']
          3: str1[i]~~str2[j]    即temp3=map[i][j]+data[str1[i-1]][str2[j-1]]
      综上所述 map[i][j]=max(temp1,temp2,temp3)
                        此时,map[aa][bb]即为最大的数。




代码如下:

#include<stdio.h>#include<string.h>int map[105][105],aa,bb;char a[105],b[105];int data[10][10]={{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 get_id(char p)      //得到每个字符对应的序号{     switch(p)     {          case 'A': return 0;          case 'C': return 1;          case 'G': return 2;          case 'T': return 3;          case '-': return 4;     }}
int MAX(int a,int b,int c)    //取三个数中的最大数{     int k;     k=a>b? a:b;     k=k>c? k:c;     return k;}
void Work()                      {     int i,j;     map[0][0]=0;                 //初始化     for(i=1;i<=aa;i++)          map[i][0]=data[get_id(a[i])][get_id('-')]+map[i-1][0];     for(j=1;j<=bb;j++)          map[0][j]=data[get_id(b[j])][get_id('-')]+map[0][j-1];     for(i=1;i<=aa;i++)            //dp部分        for(j=1;j<=bb;j++)        {           int temp1=map[i-1][j-1]+data[get_id(a[i])][get_id(b[j])];           int temp2=map[i-1][j]+data[get_id(a[i])][get_id('-')];           int temp3=map[i][j-1]+data[get_id(b[j])][get_id('-')];            map[i][j]=MAX(temp1,temp2,temp3);        }}
int main(){     int t;     scanf("%d",&t);     while(t--)     {          scanf("%d%s",&aa,a+1);          scanf("%d%s",&bb,b+1);          Work();          printf("%d\n",map[aa][bb]);     }     return 0;}




0 0
原创粉丝点击