LCS(最长公共子序列)动规算法正确性证明
今天在看代码源文件求diff的原理的时候看到了LCS算法。这个算法应该不陌生,动规的经典算法。具体算法做啥了我就不说了,不知道的可以直接看《算法导论》动态规划那一章。既然看到了就想回忆下,当想到算法正确性的时候,发现这个算法的正确性证明并不好做。于是想了一段时间,里面有几个细节很trick,容易陷进去。想了几轮,现在把证明贴出来,有异议的可以留言一起交流。
先把一些符号和约定说明下:
假设有两个数组,A和B。A[i]为A的第i个元素,A(i)为由A的第一个元素到第i个元素所组成的前缀。m(i, j)为A(i)和B(j)的最长公共子序列长度。
由于算法本身的递推性质,其实只要证明,对于某个i和j:
m(i, j) = m(i-1, j-1) + 1 (当A[i] = B[j]时)
m(i, j) = max( m(i-1, j), m(i, j-1) ) (当A[i] != B[j]时)
第一个式子很好证明,即当A[i] = B[j]时。可以用反证,假设m(i, j) > m(i-1, j-1) + 1 (m(i, j)不可能小于m(i-1, j-1) + 1,原因很明显),那么可以推出m(i-1, j-1)不是最长的这一矛盾结果。
第二个有些trick。当A[i] != B[j]时,还是反证,假设m(i, j) > max( m(i-1, j), m(i, j-1) )。
由反证假设,可得m(i, j) > m(i-1, j)。这个可以推出A[i]一定在m(i, j)对应的LCS序列中(反证可得)。而由于A[i] != B[j],故B[j]一定不在m(i, j)对应的LCS序列中。所以可推出m(i, j) = m(i, j-1)。这就推出了与反正假设矛盾的结果。
得证。
LCS(最长公共子序列)动规算法正确性证明的更多相关文章
- DP_最长公共子序列/动规入门
学自:https://open.163.com/movie/2010/12/L/4/M6UTT5U0I_M6V2U1HL4.html 最长公共子序列:(本文先谈如何求出最长公共子序列的长度,求出最长公 ...
- 算法设计 - LCS 最长公共子序列&&最长公共子串 &&LIS 最长递增子序列
出处 http://segmentfault.com/blog/exploring/ 本章讲解:1. LCS(最长公共子序列)O(n^2)的时间复杂度,O(n^2)的空间复杂度:2. 与之类似但不同的 ...
- POJ 1458 Common Subsequence(LCS最长公共子序列)
POJ 1458 Common Subsequence(LCS最长公共子序列)解题报告 题目链接:http://acm.hust.edu.cn/vjudge/contest/view.action?c ...
- 动态规划模板2|LCS最长公共子序列
LCS最长公共子序列 模板代码: #include <iostream> #include <string.h> #include <string> using n ...
- LCS 最长公共子序列
区别最长公共子串(连续) ''' LCS 最长公共子序列 ''' def LCS_len(x, y): m = len(x) n = len(y) dp = [[0] * (n + 1) for i ...
- LCS最长公共子序列(最优线性时间O(n))
这篇日志主要为了记录这几天的学习成果. 最长公共子序列根据要不要求子序列连续分两种情况. 只考虑两个串的情况,假设两个串长度均为n. 一,子序列不要求连续. (1)动态规划(O(n*n)) (转自:h ...
- LCS最长公共子序列HDU1159
最近一直在学习算法,基本上都是在学习动态规划以及字符串.当然,两者交集最经典之一则是LCS问题. 首先LCS的问题基本上就是在字符串a,b之间找到最长的公共子序列,比如 YAOLONGBLOG 和 Y ...
- LCS最长公共子序列
问题:最长公共子序列不要求所求得的字符串在所给字符串中是连续的,如输入两个字符串ABCBDAB和BDCABA,字符串BCBA和BDAB都是他们的公共最长子序列 该问题属于动态规划问题 解答:设序列X= ...
- POJ 2250(LCS最长公共子序列)
compromise Time Limit:1000MS Memory Limit:65536KB 64bit IO Format:%I64d & %I64u Descri ...
随机推荐
- 文件的copy
def mycopy(src_filename, dst_filename): try: fr = open(src_filename, "rb") try: try: fw = ...
- Android学习笔记之Toast详解
1. 贴一段Android API-Toast Toast public class Toast extends Object java.lang.Object ↳ android.widget.T ...
- AngularX Http服务总结
自己经常用的方式: 1.首先看httpModule Angular2的http访问经常采用两种方式: 共同点:导入相应的Module import {Http, RequestOptions, Res ...
- 生成代码,从 T1 到 T16 —— 自动生成多个类型的泛型
当你想写一个泛型 的类型的时候,是否想过两个泛型参数.三个泛型参数.四个泛型参数或更多泛型参数的版本如何编写呢?是一个个编写?类小还好,类大了就杯具! 事实上,在 Visual Studio 中生成代 ...
- 如何组织一个同时面向 UWP/WPF/.Net Core 控制台的 C# 项目解决方案
希望写一个小型工具,给自己和需要的人.考虑到代码尽可能的复用,我准备采用 .Net Standard 来编写大多数核心代码,并基于 .Net Core 编写跨平台控制台入口,用 WPF 编写桌面端 U ...
- 《DSP using MATLAB》示例Example 8.18
代码: %% ------------------------------------------------------------------------ %% Output Info about ...
- Apache报错You don't have permission to access on this server
解决方法: 打开httpd.conf文件 <Directory /> AllowOverride none Require all denied </Directory> 修改 ...
- direct2D图片处理
转自:http://blog.csdn.net/augusdi/article/details/9040177 Using Bitmap Brushes Direct2D 中的图片处理增加了很多的灵 ...
- groovy gradle 构建配置
参考配置 apply plugin: "idea" apply plugin: "groovy" apply plugin: "eclipse&quo ...
- C#机器学习插件 ---- AForge.NET
目录 简介 主要架构 特点 学习之旅 简介 AForge.NET是一个专门为开发者和研究者基于C#框架设计的,这个框架提供了不同的类库和关于类库的资源,还有很多应用程序例子,包括计算机视觉与人工智能, ...