LCS,即最长公共子序列。子序列的元素在原序列中的元素可以非连续,而子串的元素在原序列中的元素一定连续。LCS问题就是给定两个序列X和Y,找到它们的一个最长公共子序列。
例题如下
Common Subsequence
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 66085 Accepted Submission(s): 30723
Problem Description
A subsequence of a given sequence is the given sequence with some elements (possible none) left out. Given a sequence X = <x1, x2, ..., xm> another sequence Z = <z1, z2, ..., zk> is a subsequence of X if there exists a strictly increasing sequence <i1, i2, ..., ik> of indices of X such that for all j = 1,2,...,k, xij = zj. For example, Z = <a, b, f, c> is a subsequence of X = <a, b, c, f, b, c> with index sequence <1, 2, 4, 6>. Given two sequences X and Y the problem is to find the length of the maximum-length common subsequence of X and Y.
The program input is from a text file. Each data set in the file contains two strings representing the given sequences. The sequences are separated by any number of white spaces. The input data are correct. For each set of data the program prints on the standard output the length of the maximum-length common subsequence from the beginning of a separate line.
The program input is from a text file. Each data set in the file contains two strings representing the given sequences. The sequences are separated by any number of white spaces. The input data are correct. For each set of data the program prints on the standard output the length of the maximum-length common subsequence from the beginning of a separate line.
Sample Input
abcfbc abfcab
programming contest
abcd mnp
Sample Output
4
2
0
如果用暴力的思想,求出X的所有子序列,再验证是否为Y的子序列复杂度高达O(n2^m),无法接受。而运用动态规划求LCS,复杂度为O(nm)。
我们设dp[i][j]为第一个数组到i,第二个数组到j的LCS的长度。往下考虑,如果s1[i]==s2[j],则dp[i][j]=dp[i-1][j-1]+1,否则dp[i][j]=max(dp[i][j-1],dp[i-1][j])。状态转移方程列出,发现第i行只由第i-1行以及第i行决定。于是我们只要定义一个dp[2][m]的数组即可。
代码如下
#include<bits/stdc++.h> using namespace std; int dp[2][1005]; int main(){ string s,t; while(cin>>s>>t){ memset(dp,0,sizeof(dp)); int n=s.size(),m=t.size(); int last=0,next=1; for(int i=1;i<=n;i++){ for(int j=1;j<=m;j++){ if(s[i-1]==t[j-1])dp[next][j]=dp[last][j-1]+1; else dp[next][j]=max(dp[last][j],dp[next][j-1]); } swap(last,next); } printf("%d\n",dp[last][m]); } return 0; }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧