动态规划之最长公共子序列 代码详解

来源:互联网 发布:伊藤润二漫画全集淘宝 编辑:程序博客网 时间:2024/05/22 02:24

动态规划概念:

动态规划算法通常用于求解具有某种最优性质的问题。在这类问题中,可能会有许多可行解。每一个解都对应于一个值,我们希望找到具有最优值的解。动态规划算法与分治法类似,其基本思想也是将待求解问题分解成若干个子问题,先求解子问题,然后从这些子问题的解得到原问题的解。与分治法不同的是,适合于用动态规划求解的问题,经分解得到子问题往往不是互相独立的。若用分治法来解这类问题,则分解得到的子问题数目太多,有些子问题被重复计算了很多次。如果我们能够保存已解决的子问题的答案,而在需要时再找出已求得的答案,这样就可以避免大量的重复计算,节省时间。我们可以用一个表来记录所有已解的子问题的答案。不管该子问题以后是否被用到,只要它被计算过,就将其结果填入表中。这就是动态规划法的基本思路。

问题:最长公共序列数

给定两个字符串A和B,返回两个字符串的最长公共子序列的长度。例如,A="1A2C3D4B56”,B="B1D23CA45B6A”,”123456"或者"12C4B6"都是最长公共子序列。
给定两个字符串A和B,同时给定两个串的长度n和m,请返回最长公共子序列的长度。保证两串长度均小于等于300。
测试样例: "1A2C3D4B56",10,"B1D23CA45B6A",12
返回:6


分析:

设dp[n][m] ,为A的前n个字符与B的前m个字符的公共序列长度。

假如A的最后一个元素 与 B的最后一个元素相等,那么A和B的LCS就等于 {A减去最后一个元素} 与 {B减去最后一个元素} 的 LCS  再加上 A和B相等的最后一个元素。(当A[n]==B[m]的时候,dp[i][j] = max(dp[i-1][j-1]+1,dp[i-1][j],dp[i][j-1]))

假如A的最后一个元素 与 B的最后一个元素不等(本例子就是属于这种情况),那么A和B的LCS就等于 : {A减去最后一个元素} 与 B 的LCS, {B减去最后一个元素} 与 A 的LCS 中的最大的那个序列。(当A[n]!=B[m]的时候,dp[i][j] = Math.max(dp[i-1][j],dp[i][j-1]))




代码:

  1. public class LCS {  
  2.     public int findLCS(String A, int n, String B, int m) {  
  3.         // write code here  
  4.         int[][] dp = new int[n][m];  
  5.         char[] a = A.toCharArray();  
  6.         char[] b = B.toCharArray();  
  7.        for(int i=0;i<n;i++){  
  8.            if(a[i]==b[0]){  
  9.                dp[i][0] = 1;  
  10.                for(int j=i+1;j<n;j++){      //灰色部分用于初始化当A或B字符串长度为一的情
  11.     //况(最基本的部分),为后面求长度准备数据。
  12.                    dp[j][0] = 1;  
  13.                }  
  14.                break;  
  15.            }  
  16.              
  17.        }  
  18.          for(int i=0;i<m;i++){  
  19.            if(a[0]==b[i]){  
  20.                dp[0][i] = 1;  
  21.                for(int j=i+1;j<m;j++){  
  22.                    dp[0][j] = 1;  
  23.                }  
  24.                break;  
  25.            }  
  26.              
  27.        }  
  28.        for(int i=1;i<n;i++){  
  29.            for(int j=1;j<m;j++){  
  30.                if(a[i]==b[j]){  
  31.                   dp[i][j] = max(dp[i-1][j-1]+1,dp[i-1][j],dp[i][j-1]);  
  32.                }else{  
  33.                    dp[i][j] = Math.max(dp[i-1][j],dp[i][j-1]);  
  34.                }  
  35.                      
  36.            }  
  37.        }   
  38.           
  39.         return dp[n-1][m-1];  
  40.     }  
  41.     public int max(int a,int b,int c){  
  42.         int max = a;  
  43.         if(b>max)  
  44.             max=b;  
  45.         if(c>max)  
  46.             max = c;  
  47.         return max;  
  48.     }


原创粉丝点击