• 经典dp 最长公共子序列


    首先,说明一下子序列的定义……

    一个序列A={a1,a2,a3,...,an},从中删除任意若干项,剩余的序列叫A的一个子序列。

    很明显(并不明显……),子序列……并不需要元素是连续的……(一开始的时候思维总是以为元素是连续的,好傻啊……)

    然后是公共子序列……

    如果C是A的子序列,也是B的子序列,那么C是A和B的公共子序列……

    公共子序列一般不止一个,最长的那个就是最长公共子序列,当然也可能不止一个……

    煮个栗子……

    A={1,3,6,9,5,4,8,7},B={1,6,3,4,5,7}

    {1,4,7}是A和B的公共子序列

    {1,3,4,7}是A和B的最长公共子序列

    好了,说明的部分就到这,接下来,进入解决问题的部分……

    给出序列A={a1,a2,a3...an},B={b1,b2,b3...bn}

    我们用lcs[i][j]来表示A的前i项和B的前j项的最长公共子序列的长度

    flag[i][j]表示这一点是由哪点继承来的,然后,开始搜索……

    如果……

    (1)A[i]==B[j]

    那么就代表lcs[i][j]的最后一项一定是A[i],就是在lcs[i-1][j-1]接上A[i],也就是lcs[i][j]=lcs[i-1][j-1]+1,并记录flag[i][j]

    (2)A[i]!=B[j]

    那么lcs[i][j]=max(lcs[i-1][j-1],lcs[i][j-1]),因为既然接不上,那就继承一个长一点的留着呗,不要忘记了flag[i][j]的数字是不同的亲~

    可能我说的比较简略,上一张比较好理解的图……

    可能第一次看会很凌乱,仔细看吧亲……

    最后按flag打出来就好了~

    最后上代码

     1 #include<stdio.h>
     2 #include<string.h>
     3 int lcs[1005][1005];
     4 int flag[1005][1005];
     5 char a[1005],b[1005];
     6 void findlcs(char a[],char b[],int lena,int lenb){
     7     int i,j;
     8     for(i=1;i<=lena;i++)
     9         for(j=1;j<=lenb;j++){
    10             if(a[i-1]==b[j-1]){
    11                 lcs[i][j]=lcs[i-1][j-1]+1;
    12                 flag[i][j]=1;
    13             }
    14             else{
    15                 if(lcs[i][j-1]>lcs[i-1][j]){
    16                     lcs[i][j]=lcs[i][j-1];
    17                     flag[i][j]=2;
    18                 }
    19                 else{
    20                     lcs[i][j]=lcs[i-1][j];
    21                     flag[i][j]=3;
    22                 }
    23             }
    24         }
    25 }
    26 void printlcs(char a[],char b[],int lena,int lenb){
    27     int i=lena;
    28     int j=lenb;
    29     int len=0;
    30     int rec[1050];
    31     while(i>0&&j>0){
    32         if(flag[i][j]==1){
    33             rec[len++]=a[i-1];
    34             i--,j--;
    35         }
    36         else if(flag[i][j]==2) j--;
    37         else if(flag[i][j]==3) i--;
    38     }
    39     len--;
    40     while(len>=0){
    41         printf("%c",rec[len--]);
    42     }
    43     printf("
    ");
    44 }
    45 int main(){
    46     while(~scanf("%s%s",a,b)){
    47         int lena=strlen(a);
    48         int lenb=strlen(b);
    49         findlcs(a,b,lena,lenb);
    50         printlcs(a,b,lena,lenb);
    51         memset(flag,0,sizeof(flag));
    52         memset(lcs,0,sizeof(lcs));
    53     }
    54     return 0;
    55 }
    View Code
  • 相关阅读:
    drf之序列化组件
    RESTful API和Django的drf安装及使用
    Django之CBV中View、APIView源码分析
    Ajax以及crsf的校验
    Django之中间件
    Django之Auth用户认证模块
    Django之cookie、session以及FBV和CBV
    Django之Forms组件
    Django之ORM
    Django基本知识、路由层、视图层、模版层
  • 原文地址:https://www.cnblogs.com/general10/p/5255605.html
Copyright © 2020-2023  润新知