动态规划入门之LCS(2)

本文深入探讨了如何通过控制语句确保序列严格单调递增,从而解决最长公共子序列(LICS)问题。通过引入新的动态规划公式和详细代码实现,阐述了解题过程和关键思路。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


LICS问题是在最长公共子序列(LCS)基础上,要求还要序列是严格单调递增的。
本来是打算在LCS代码的基础上:
<span style="font-size:14px;">if(a[i-1]==b[j-1]) dp[i][j]=dp[i-1][j-1]+1;</span>
<span style="font-size:14px;">else dp[i][j]=max{dp[i-1][j],dp[i][j-1]};</span>
<span style="font-size:14px;">
</span>
<span style="font-size:14px;">加上控制语句使得序列严格单调递增,但是始终没有想出来。
参考网上其他人博客,发现网上千篇一律都是另一种解法。</span>
</pre><pre class="java" name="code" snippet_file_name="blog_20160211_5_6770872" code_snippet_id="1576943">定义新的dp公式: d[j]代表a[1..i]与b[1..j]的LICS长度。
</pre><pre class="java" name="code" snippet_file_name="blog_20160211_7_4579045" code_snippet_id="1576943">d[j]=max+1,其中max为在b[k]小于a[i]前提下d[k]的最大值(k=1,..,j)。
</pre><pre class="java" name="code" snippet_file_name="blog_20160211_9_8799166" code_snippet_id="1576943">(ps:多思考,多动手,才容易理解)
</pre><pre class="java" name="code" snippet_file_name="blog_20160211_11_4655492" code_snippet_id="1576943"><span style="font-size:14px;">
import java.util.Scanner;

public class Main {
	public static void main(String[] args) {
		Scanner scan = new Scanner(System.in);
		int T = scan.nextInt();
		while (T-- != 0) {
			int n = scan.nextInt();
			int[] a = new int[n + 1];
			for (int i = 1; i <= n; i++) {
				a[i] = scan.nextInt();
			}
			int m = scan.nextInt();
			int[] b = new int[m + 1];
			for (int i = 1; i <= m; i++) {
				b[i] = scan.nextInt();
			}
			int[] d = new int[m + 1];
			for (int i = 1; i <= n; i++) {// a数组前i个字符
				int max = 0;
				for (int j = 1; j <= m; j++) {// b数组前j个字符,但确定以bj为结尾
					if (b[j] < a[i] && max < d[j]) {
						max = d[j];
					}
					if (a[i] == b[j]) {
						d[j] = max + 1;
					}

				}
			}
			int max = 0;
			// 遍历所有以bj为结尾的LICS长度
			for (int j = 1; j <= m; j++) {
				if (max < d[j]) {
					max = d[j];
				}
			}
			System.out.println(max);

		}

	}
}
</span>


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值