奇妙的算法之LCS妙解
欢迎大家访问handsomecui的博客,转载请注明地址https://www.cnblogs.com/handsomecui,欢迎加入技术群讨论:778757421
LCS算法妙解
LCS问题简述:最长公共子序列
一个数列 S,如果分别是两个或多个已知数列的子序列,且是所有符合此条件序列中最长的,则S 称为已知序列的最长公共子序列。
LCS问题的分支:最长公共子串与最长公共子序列
子串(Substring)是串的一个连续的部分,子序列(Subsequence)则是从不改变序列的顺序,而从序列中去掉任意的元素而获得的新序列;更简略地说,前者(子串)的字符的位置必须连续,后者(子序列LCS)则不必。比如字符串acdfg同akdfc的最长公共子串为df,而他们的最长公共子序列是adf。
LCS解题策略:
one:穷举法。。。复杂度不再多说,想想2的N次方就感到可怕;
two:矩阵,也就是动态规划节LCS问题,也就是今天咱的标题;
下面来细讲the twith idea:
由此图可以看出此经典算法的思路;
下面是代码,方便大家理解:
1 #include<stdio.h> 2 #include<string.h> 3 #define MAX(a,b) (a>b?a:b) 4 const int MAXN=1010; 5 int dp[MAXN][MAXN]; 6 char a[MAXN],b[MAXN]; 7 int main(){ 8 while(~scanf("%s%s",a+1,b+1)){ 9 memset(dp,0,sizeof(dp)); 10 int i,j; 11 for( i=1;a[i];i++){ 12 for(j=1;b[j];j++){ 13 if(a[i]==b[j])dp[i][j]=dp[i-1][j-1]+1; 14 else dp[i][j]=MAX(dp[i][j-1],dp[i-1][j]); 15 } 16 } 17 printf("%d\n",dp[i-1][j-1]); 18 } 19 return 0;}
此递归关系为:
- 若xm=yn,则zk=xm=yn且Zk-1是Xm-1和Yn-1的最长公共子序列;
- 若xm≠yn且zk≠xm ,则Z是Xm-1和Y的最长公共子序列;
- 若xm≠yn且zk≠yn ,则Z是X和Yn-1的最长公共子序列。
此算法时间复杂度为n*m,空间复杂度也是n*m;
另外若要记录路径就比较复杂了;
lcs解决lis问题:
需要先排序,然后与原数组求最长公共子序列;
下面是道题poj上的,就用到了此题的思想:
Time Limit: 1000MS | Memory Limit: 10000K | |
Total Submissions: 43194 | Accepted: 17514 |
Description
Input
Output
Sample Input
abcfbc abfcab programming contest abcd mnp
Sample Output
4 2 0
还有南阳oj上面有道最长公共子序列更是LCS的模板;
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 提示词工程——AI应用必不可少的技术
· Open-Sora 2.0 重磅开源!
· 周边上新:园子的第一款马克杯温暖上架