最长公共子序列
程序员文章站
2024-03-17 22:04:16
...
最长公共子序列
最长公共子序列是经典的动态规划问题,下面从动态规划的两个重要特征,最优子结构和
子问题重叠来分析问题,同时要保证子问题的完整性。
-
最优子结构
最优子结构的意思就是原问题的最优解中包含子问题的最优解
原问题:, 是两个序列,求最长的
使得同时是的子序列
假设是原问题的最优解,则以下成立
-
如果,则是子问题求和
的最长公共子序列的最优解
-
如果,则是子问题求和的
最长公共子序列的最优解,或者是子问题求和的最
长公共子序列的最优解
证明
-
如果不是子问题的最优解,则存在比其更长的公共子序列是子问题
的最优解,则原问题存在比更长的最优解,与假设矛盾,故不成立
-
如果不是子问题的最优解,则存在比其更长的公共子序列是子问题的
最优解,在这种情况下原问题的最优解得长度就会大于,与假设矛盾
或者的情况证明类似
-
-
子问题重叠
假设是长度分别为m和n的序列的最大公共子序列的长度,则由上面可以得到
一下公式:
从公式可以看出,求解原问题的时候回重复计算某些子问题 -
实例 POJ1458
AC代码
import java.util.Scanner; import java.io.File; import java.io.FileNotFoundException; public class Main{ public static void main(String args[]) { try{ Scanner scanner = new Scanner(System.in); int arr[][] = new int[1000][1000]; while(scanner.hasNext()) { String X = scanner.next(); String Y = scanner.next(); int m = X.length(); int n = Y.length(); for(int i = 0; i <= m; i++) for(int j = 0; j <= n; j++) arr[i][j] = 0; for(int i = 1; i <= m; i++) for(int j = 1; j <= n; j++) { if(X.charAt(i-1) == Y.charAt(j-1)) { arr[i][j] = arr[i-1][j-1] + 1; }else{ arr[i][j] = Math.max(arr[i-1][j], arr[i][j-1]); } } System.out.println(arr[m][n]); } }catch(Exception e) { e.printStackTrace(); } } }