蓝桥杯——说好的进阶之最长公共子序列



一个序列S,若分别是两个或多个已知序列的子序列,且是所有符合条件序列中最长的,则S称为已知序列的最长公共子序列(LCS)。

利用最长公共子序列,可以求解出最长递增子序列问题

	/*
	 * 
	 * 输入: 
	 * 1324
	 * 	 
	 * 1234
	 * 
	 * 输出: length:3 
	 * 子序列:1 2 4
	 * 
	 * 也可以用来求解最长递增子序列问题
	 * 将所求序列进行排序,再求LCS即可
	 */
	static int[][] v;
	static int[][] p;
	static String a;
	static String b;

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Scanner scanner = new Scanner(System.in);
		a = scanner.nextLine();
		b = scanner.nextLine();

		cal(a, b);

		get_lcs(a.length(), b.length());
	}

	static void cal(String a, String b) {
		char[] a_arr = a.toCharArray();
		char[] b_arr = b.toCharArray();
		v = new int[a_arr.length + 1][b_arr.length + 1];
		p = new int[a_arr.length + 1][b_arr.length + 1];
		for (int i = 1; i < v.length; i++) {
			for (int j = 1; j < v[0].length; j++) {
				if (a_arr[i - 1] == b_arr[j - 1]) {
					v[i][j] = v[i - 1][j - 1] + 1;
					p[i][j] = 1;
				} else if (v[i - 1][j] > v[i][j - 1]) {
					v[i][j] = v[i - 1][j];
					p[i][j] = 2;
					// v[i][j] = Math.max(v[i - 1][j], v[i][j - 1]);
				} else {
					v[i][j] = v[i][j - 1];
					p[i][j] = 3;
				}
			}
		}

		for (int[] i : v) {
			for (int j : i) {
				System.out.print(j + " ");
			}
			System.out.println();
		}
		System.out.println("最长子序列length:" + v[a_arr.length][b_arr.length]
				+ "\n最长子序列:");
	}

	static void get_lcs(int i, int j) {
		if (i == 0 || j == 0) {
			return;
		}
		if (p[i][j] == 1) {
			get_lcs(i - 1, j - 1);
			System.out.print(a.charAt(i - 1) + " ");
		}
		if (p[i][j] == 2) {
			get_lcs(i - 1, j);
		}
		if (p[i][j] == 3) {
			get_lcs(i, j - 1);
		}
	}

你可能感兴趣的:(算法,蓝桥杯,java,算法,蓝桥杯,最长公共子序列)