• 最长公共子序列-动态规划


    子序列:序列 X<A,B,C,D,E,F> , <A> <A,B> <A,C,E> <A,B,C,D,E,F>等等都为X。

    最长公共子序列:两个序列的公共子序列最长的那个。

    问题分析:

    给定两个序列:

     

    定义个C数组,存储当x1中只有0~7个元素时与y1中只有0~6个元素的最长公共子序列。

    假设x1中没有元素时,最长公共子序列:0

    x1中只有一个元素A时:

    x1中两个元素A B时:

    红框是x1中 B 与y1中 D比较,不相等,有两种情况,B的前一个元素的最大子段和 或 B与D前的最大子段和,它们取大值,代码:C[i][j] = ( C[i-1][j] > C[i][j-1]?C[i-1][j]:C[i][j-1] );

    绿框是x1中 B 与y1中 B比较,相等,一种情况,x1中B前一个元素到y1中B前的最大子段和+1,代码:C[i][j] = C[i-1][j-1]+1;

     最后得出C数组:                                                                             

                                                                     rec数组: 从下标结尾开始,if=0,向上移;if=1,a[i]值存入c数组;if=-1,向左移。

                                    

    输入:

    7 6
    A B C B D A B
    B D C A B A

    输出:

    B C B A
    4

    代码:

    #include<iostream>
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    using namespace std;
    
    int main()
    {
        int rec[100][100];//记录最大子段和字符位置
        char a[100],b[100],c[100];//c数组存储最后最大子段和的字符
        int C[100][100]= {0};//记录最大子段和
        int len_a,len_b;
        cin>>len_a>>len_b;
        for(int i=1; i<=len_a; i++)
        {
            cin>>a[i];
        }
        for(int i=1; i<=len_b; i++)
        {
            cin>>b[i];
        }
        for(int i=1; i<=len_a; i++)
        {
            for(int j=1; j<=len_b; j++)
            {
                if(a[i]==b[j])
                {
                    C[i][j]=C[i-1][j-1]+1;
                    rec[i][j]=1;
                }
                else
                {
                    C[i][j]=(C[i-1][j]>C[i][j-1]?C[i-1][j]:C[i][j-1]);
                    if(C[i][j]==C[i-1][j])
                    {
                        rec[i][j]=0;
                    }
                    else
                    {
                        rec[i][j]=-1;
                    }
                }
            }
        }
        //将最大子段和的字符存入c数组
        int i=len_a,j=len_b,num=C[i][j];
        while(num>0)
        {
            if(rec[i][j]==1)
            {
                c[num--]=a[i];
                i--,j--;
            }
            else if(rec[i][j]==0)
            {
                i--;
            }
            else
            {
                j--;
            }
        }
        //输出最大子段和字符
        for(i=1;i<=C[len_a][len_b];i++)
        {
            cout<<c[i]<<" ";
        }
        cout<<endl;
        cout<<C[len_a][len_b];  //输出最大子段和个数
        return 0;
    }
  • 相关阅读:
    jQuery UI DatePicker用法和中文设置
    jQuery的ajax方法
    jQuery遍历复杂的JSON数据
    JavaScript面向对象的写法
    jpa
    日志
    全局异常的处理!
    oracle表空间
    plsql的连接配置
    pLsql使用
  • 原文地址:https://www.cnblogs.com/xxaf/p/12887844.html
Copyright © 2020-2023  润新知