zoukankan      html  css  js  c++  java
  • 最长公共子序列

    原创


    动态规划解最长公共子序列问题

    设序列一的序列为:Ai(1<=i<=n)

    序列二的序列为:Bj(1<=j<=m)

    最长公共子序列为:Ck(1<=k<=z)

    能用动态规划解的题目都是可以将原规模的题分解成子问题规模,公共子序列问题可以这样分解:

    如果存在An==Bm==Cz,则Ai(1<=i<=n-1)和Bj(1<=j<=m-1)的最长公共子序列为:Ck(1<=k<=z-1)

    如果存在An!=Bm,且An!=Cz,则Ai(1<=i<=n-1)和Bj(1<=j<=m)的最长公共子序列为:Ck(1<=k<=z)

    如果存在An!=Bm,且Bm!=Cz,则Ai(1<=i<=n)和Bj(1<=j<=m-1)的最长公共子序列为:Ck(1<=k<=z)

    利用上述的关系式我们自顶向下的求最长公共子序列长度。

    设数组F[ i ][ j ]表示序列一的长度为i,序列二的长度为j时的最长公共子序列长度,显而易见,当i==0或者j==0时,

    即存在其中一个序列没有元素时,F[i][j]都是0,然后利用上述的关系式可以继续往下求。

    当A[i]==B[j]时,F[i][j]=F[i-1][j-1]

    当A[i-1]!=B[j]时,max{ F[i][j-1],F[i-1][j] }

    上面为什么要选出一个最大的呢?

    假如是An!=Bm,且An!=Cz这种情况,我们可以知道应该铲除Ai的最后一个元素An,公共子序列长度和原规模

    问题的公共子序列长度是相同的,但是如果铲除了Bm,则公共子序列长度肯定会小于等于原规模的公共子序列长度。

    为什么会小于等于自己理解了!

     1 import java.util.Scanner;
     2 
     3 public class 算法分析与设计3_1 {
     4     
     5     static void LCS(int m,int n,int A[],int b[][]){
     6         if(m==0 || n==0)return;
     7         if(b[m][n]==1){
     8             LCS(m-1,n-1,A,b);
     9             System.out.print(A[m]+" ");
    10         }else if(b[m][n]==2){
    11             LCS(m-1,n,A,b);
    12         }else{
    13             LCS(m,n-1,A,b);
    14         }
    15     }
    16 
    17     static void LCSLength(int A[],int B[],int C[][],int m,int n,int b[][]){
    18         for(int i=0;i<=m;i++){
    19             C[i][0]=0;    //B序列无元素 
    20         }
    21         for(int i=0;i<=n;i++){
    22             C[0][i]=0;    //A序列无元素
    23         }
    24         for(int i=1;i<=m;i++){
    25             for(int j=1;j<=n;j++){
    26                 if(A[i]==B[j]){
    27                     C[i][j]=C[i-1][j-1]+1;
    28                     b[i][j]=1;    //斜上方 
    29                 }else if(C[i-1][j]>=C[i][j-1]){
    30                     C[i][j]=C[i-1][j];
    31                     b[i][j]=2;    //上一行 
    32                 }else{
    33                     C[i][j]=C[i][j-1];
    34                     b[i][j]=3;    //上一列 
    35                 }
    36             } 
    37         }
    38         LCS(m,n,A,b);
    39     }
    40 
    41     public static void main(String[] args) {
    42         Scanner reader=new Scanner(System.in);
    43         int A[]=new int[1000];
    44         int B[]=new int[1000];
    45         int C[][]=new int[1000][1000];
    46         int b[][]=new int[1000][1000];
    47         System.out.print("输入第一个序列的大小:");
    48         int A_size=reader.nextInt();
    49         System.out.print("输入第一个序列的值:");
    50         for(int i=1;i<=A_size;i++){
    51             A[i]=reader.nextInt();
    52         }
    53         System.out.print("输入第二个序列的大小:");
    54         int B_size=reader.nextInt();
    55         System.out.print("输入第二个序列的值:");
    56         for(int i=1;i<=B_size;i++){
    57             B[i]=reader.nextInt();
    58         }
    59         System.out.print("最长公共子序列为:");
    60         LCSLength(A,B,C,A_size,B_size,b);
    61         System.out.println("长度为:"+C[A_size][B_size]);
    62         reader.close();
    63     }
    64 
    65 }

    10:34:09

    2018-10-28

  • 相关阅读:
    iOS开发-ScrollView图片缩放
    算法-随机不重复数列生成
    iOS开发-舒尔特表
    iOS开发-音乐播放
    iOS开发-简单的图片查看器
    iOS开发-Interface Builder的前世今生
    iOS开发-DatePicker控件
    iOS开发-UI基础Demo
    Objective-C-Category类别
    Objective-C面向对象之实现类
  • 原文地址:https://www.cnblogs.com/chiweiming/p/9864769.html
Copyright © 2011-2022 走看看