本文最后更新于:January 27, 2022 pm
纸上得来终觉浅,绝知此事要躬行。路漫漫其修远兮,吾将上下而求索!知识是经过历史的巨人沉淀下来的,别总想着自己能够快速学会,多花点时间去看看,也许会发现些不同的东西。你能快速学会的、觉得简单的东西,对于别人来说也是一样的。人外有人,天外有天。当努力到达了一定的程度,幸运自会与你不期而遇。
目录
求公共子序列长度
状态转移方程:
dp[i][j] = max(dp[i-1][j], dp[i][j-1],dp[i-1][j-1] + (A[i]==B[j] ? 1 : 0))
,表示在这三种状态中取到最大值。
(1)第一种状态表示不录入第一个序列的第i个字符时的最长公共子序列,
(2)第二种状态表示不录入第二个序列的第j个字符时的最长公共子序列,
(3)第三种状态表示第一个序列的前i-1个字符与第二个序列前j-1个字符的公共子序列加上最后一个字符的录入状态,如果最后的一个字符相等则录入,状态为1,否则不录入,状态为0。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76
| import java.io.*; import java.text.SimpleDateFormat; import java.util.*;
public class Main { public static BufferedReader in = new BufferedReader(new InputStreamReader(System.in)); public static BufferedWriter out = new BufferedWriter(new OutputStreamWriter(System.out)); public static StreamTokenizer cin = new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in))); public static PrintWriter cout = new PrintWriter(new OutputStreamWriter(System.out)); public static Scanner sc = new Scanner(System.in);
public static int maxd = 10000+7; public static int INF = 0x3f3f3f3f; public static int mod = 998244353; public static int[][] dp = new int[maxd][maxd];
public static void lcs(char[] x,char[] y){ int lenx = x.length; int leny = y.length; for(int i=1;i<=lenx;++i){ for(int j=1;j<=leny;++j){ if(x[i-1]==y[j-1]) dp[i][j] = dp[i-1][j-1]+1; else dp[i][j] = Math.max(dp[i-1][j],dp[i][j-1]); } }
}
public static void main(String[] args) throws Exception { String s1 = nextString(); String s2 = nextString(); lcs(s1.toCharArray(),s2.toCharArray()); System.out.println(dp[s1.length()][s2.length()]);
closeAll(); }
public static void cinInit(){ cin.wordChars('a', 'z'); cin.wordChars('A', 'Z'); cin.wordChars(128 + 32, 255); cin.whitespaceChars(0, ' '); cin.commentChar('/'); cin.quoteChar('"'); cin.quoteChar('\''); cin.parseNumbers(); } public static int nextInt() throws Exception { cin.nextToken(); return (int) cin.nval; } public static long nextLong() throws Exception { cin.nextToken(); return (long) cin.nval; } public static double nextDouble() throws Exception { cin.nextToken(); return cin.nval; } public static String nextString() throws Exception { cin.nextToken(); return cin.sval; } public static void closeAll() throws Exception { cout.close(); in.close(); out.close(); } }
|
测试数据
输入:
| abcfbc abfcab programming contest abcd mnp
|
输出:
求公共子序列
根据动态规划的状态,来判断我们要求得的序列中的字符有哪些。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100
| import java.io.*; import java.text.SimpleDateFormat; import java.util.*;
public class Main { public static BufferedReader in = new BufferedReader(new InputStreamReader(System.in)); public static BufferedWriter out = new BufferedWriter(new OutputStreamWriter(System.out)); public static StreamTokenizer cin = new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in))); public static PrintWriter cout = new PrintWriter(new OutputStreamWriter(System.out)); public static Scanner sc = new Scanner(System.in);
public static int maxd = 10000+7; public static int INF = 0x3f3f3f3f; public static int mod = 998244353; public static int[][] dp = new int[maxd][maxd];
public static void lcs(char[] x,char[] y){ int lenx = x.length; int leny = y.length; for(int i=1;i<=lenx;++i){ for(int j=1;j<=leny;++j){ if(x[i-1]==y[j-1]) dp[i][j] = dp[i-1][j-1]+1; else dp[i][j] = Math.max(dp[i-1][j],dp[i][j-1]); } } } public static char[] LCSstr(char[] x,char[] y){ char[] ch = new char[maxd]; int i = x.length; int j = y.length; int ind = 0; while(i!=0 && j!=0){ if(x[i-1]==y[j-1]){ ch[ind++]=x[--i]; j--; }else if(dp[i][j-1]>dp[i-1][j]) { j--; }else if(dp[i][j-1]<=dp[i-1][j]){ i--; } } return ch; }
public static void main(String[] args) throws Exception { String s1 = nextString(); String s2 = nextString(); lcs(s1.toCharArray(),s2.toCharArray());
char[] ans = LCSstr(s1.toCharArray(),s2.toCharArray()); System.out.println(dp[s1.length()][s2.length()]);
int rlen = dp[s1.length()][s2.length()]; for(int i=rlen-1;i>=0;--i){ System.out.print(ans[i]); } System.out.println();
closeAll(); }
public static void cinInit(){ cin.wordChars('a', 'z'); cin.wordChars('A', 'Z'); cin.wordChars(128 + 32, 255); cin.whitespaceChars(0, ' '); cin.commentChar('/'); cin.quoteChar('"'); cin.quoteChar('\''); cin.parseNumbers(); } public static int nextInt() throws Exception { cin.nextToken(); return (int) cin.nval; } public static long nextLong() throws Exception { cin.nextToken(); return (long) cin.nval; } public static double nextDouble() throws Exception { cin.nextToken(); return cin.nval; } public static String nextString() throws Exception { cin.nextToken(); return cin.sval; } public static void closeAll() throws Exception { cout.close(); in.close(); out.close(); } }
|
测试数据
输入:
输出: