当前位置: 首页 > news >正文

动态规划 -- 最长公共子序列

最长公共子序列的结构

设序列 X={x1,x2,…,x m} 和 Y={y1,y2,…,y n} 的最长公共子序列为 Z={z1,z2,…,z k},则有以下结论:

  1. 若 x m=y n,则 z k=x m=y n,且 Z k−1(即 Z 去掉最后一个元素 z k 后的子序列)是 X m−1(即 X 去掉最后一个元素 x m 后的子序列)和 Y n−1(即 Y 去掉最后一个元素 y n 后的子序列)的最长公共子序列。

  2. 若 x m\=y n 且 z k\=x m,则 Z 是 X m−1 和 Y 的最长公共子序列。

  3. 若 x m\=y n 且 z k\=y n,则 Z 是 X 和 Y n−1 的最长公共子序列。

动规方程

c[i] [j]记录序列X和Y的最长公共子序列长度

代码实现

求最长子序列长度
int LCSLength(const char* X, const char* Y, int i, int j) { if (i == 0 || j == 0) { return 0; } else if (X[i] == Y[j]) { return LCSLength(X, Y, i - 1, j - 1) + 1; } else { int t1 = LCSLength(X, Y, i - 1, j);// X int t2 = LCSLength(X, Y, i, j - 1); if (t1 > t2) { return t1; } else { return t2; } } } ​ int main() { const int xm = 7; const int yn = 6; char X[xm + 1] = { '#','A','B','C','B','D','A','B' }; char Y[yn + 1] = { '#','B','D','C','A','B','A' }; ​ int maxlen = LCSLength(X, Y, xm, yn); cout << "maxlen: " << maxlen << endl; ​ return 0; }
求最长子序列(并优化防止重复计算)
int main() { const int xm = 7; const int yn = 6; char X[xm + 1] = { '#','A','B','C','B','D','A','B' }; // 0 1 2 3 4 5 6 7 // X[xm] char Y[yn + 1] = { '#','B','D','C','A','B','A' }; ​ std::vector<std::vector<int> > c(xm + 1, std::vector<int>(yn + 1, 0)); std::vector<std::vector<int> > s(xm + 1, std::vector<int>(yn + 1, 0)); printf("c vec: \n"); Print2Vec(c); printf("s vec: \n"); Print2Vec(s); int maxlen = LCSLength(X, Y, xm, yn,c,s); cout << "maxlen: " << maxlen << endl; cout << "num: " << num << endl; printf("c vec: \n"); Print2Vec(c); printf("s vec: \n"); Print2Vec(s); printf("data: \n"); LCS(X, xm, yn, s); return 0; }
不用递归实现
void Print2Vec(const std::vector<std::vector<int> >& c) { int yn = c[0].size(); int xm = c.size(); printf(" "); for (int i = 0; i < yn; ++i) { printf("%5d", i); } printf("\n"); for (int i = 0; i < xm; ++i) { printf("%3d ", i); for (int j = 0; j < yn; ++j) { printf("%5d", c[i][j]); } printf("\n"); } printf("\n---------------------------\n"); } int NiceLCSLength(const char* X, const char* Y, int xm, int yn, std::vector<std::vector<int> >& c, std::vector<std::vector<int> >& s) { for (int i = 1; i <= xm; ++i) // X { for (int j = 1; j <= yn; ++j) { if (X[i] == Y[j]) { c[i][j] = c[i - 1][j - 1] + 1; s[i][j] = 1; } else { if (c[i - 1][j] > c[i][j - 1]) { c[i][j] = c[i - 1][j]; s[i][j] = 2; } else { c[i][j] = c[i][j - 1]; s[i][j] = 3; } } } Print2Vec(c); } return c[xm][yn]; }
http://www.jsqmd.com/news/561439/

相关文章:

  • 三步搞定网页资源捕获与高效下载:猫抓插件全攻略
  • Qwerty Learner存储架构进化论:从需求到落地的技术决策指南
  • 深度解析pymobiledevice3:iOS设备调试与管理的Python终极方案
  • 别再瞎找了!高效论文写作全流程AI论文写作工具推荐(2026 最新)
  • CenterPoint实战:基于中心点热力图的三维目标检测与跟踪技术解析
  • Qwen3-TTS开源模型快速上手:5分钟完成中文普通话+粤语+英文三语语音合成
  • DeOldify API速率限制:令牌桶算法实现每用户每小时1000次调用
  • 算力服务器都有哪些功能
  • 如何利用开源数学资源库构建系统化学习路径
  • YOLOv12:以注意力机制重塑实时目标检测的精度与速度边界
  • 三级淋巴结构TLS在癌症中的应用
  • 别再只盯着PID了!用STM32 HAL库的PWM差速,让你的5路红外寻迹小车先跑起来
  • PyTorch 2.5镜像体验:预装全套工具,让AI项目开发效率翻倍
  • java中类的数组定义和使用 类数组的创建和遍历方法
  • 告别论文格式内耗!从标题层级到参考文献,这款工具一键搞定全流程合规排版
  • 如何在Mac上快速制作Windows启动盘:WinDiskWriter的完整指南
  • 别再复制粘贴官方文档了!用Python调用通义千问API的3个实战项目(含完整代码)
  • 北海特色美食哪家好
  • 圆钢自动下料机的设计【说明书 CAD图纸 开题报告 中期报告 实习报告 外文翻译】
  • 3步精通Calibre电子书转换:从格式兼容到专业排版指南
  • OpCore Simplify:革新黑苹果配置流程——从繁琐到智能的EFI构建方案
  • 主流AI论文写作工具梯队划分(2026 权威发布)
  • 流程越来越规范,但员工体验却越来越差
  • 怎么搭建OpenClaw?2026年本地小白10分钟部署、配置阿里云百炼API 保姆级步骤
  • CenOS中clang-format的安装与常见问题解决指南
  • Skills 如何高效地扩展 Claude 的能力
  • 开源游戏串流方案:Sunshine打造低延迟跨设备游戏体验
  • 2026年网文实测:我用这套AI消痕组合拳,连责编都没看出来AIGC痕迹
  • PX4+ROS实战:保姆级教程解决MAVROS安装后GeographicLib数据缺失报错
  • 功能越来越多,但 IT 系统却越来越难用了