First and second line of each input case contain two strings of lowercase character a…z. There are no spaces before, inside or after the strings. Lengths of strings do not exceed 100.
For each case, output k – the length of a longest common subsequence in one line.
abcd cxbydz
2
#include<iosteream> #include<cstring> using namespace std; int c[105][105];//用于存储动态转移方程 int main() { string str1,str2; cin>>str1>>str2; int len1=str1.length(),len2=str2.length(); memset(c,0,sizeof(c));//初始化动态转移方程 /*核心部分*/ for(int i=1;i<=len1;i++) { for(int j=1;j<=len2;j++) { if(str1[i-1]==str2[j-1]) { c[i][j]=max(c[i][j],c[i-1][j-1]+1); } else { c[i][j]=max(c[i-1][j],c[i][j-1]); } } } /*****************/ cout<<c[len1][len2]<<endl; return 0; }
//LCS最长公共子序列 //动态规划 //dp[i][j]表示str1的前i个字符和str2的前j个字符的最长公共子序列 //假设str1第i位=str2第j位,那么此时的最长公共子序列等于dp[i-1][j-1]+1 //如果不相等,那么最长公共子序列等于dp[i][j-1]、dp[i-1][j]中的较大值 //要注意的是我们比较的是第i位和第j位的值,所以是str1[i-1] str2[j-1] //时间复杂度为O(len1*len2*1) #include<stdio.h> #include<string.h> int max(int x,int b){ if(x>b) return x; return b; } int main(){ char str1[101]; char str2[101]; int dp[101][101]; while(scanf("%s %s",str1,str2)!=EOF){ int len1=strlen(str1); int len2=strlen(str2); for(int i=0;i<=len1;i++){ dp[i][0]=0; } for(int j=0;j<=len2;j++){ dp[0][j]=0; } for(int i=1;i<=len1;i++){ for(int j=1;j<=len2;j++){ if(str1[i-1]==str2[j-1]){ dp[i][j]=dp[i-1][j-1]+1; }else{ dp[i][j]=max(dp[i-1][j],dp[i][j-1]); } } } printf("%d\n",dp[len1][len2]); } }
#include<bits/stdc++.h> using namespace std; int dp[100][100];//dp[i][j]表示str1中以i为末尾的字符串和str2中以j为末尾的字符串的公共子串长度 char str1[100]; char str2[100]; int main(){ while(scanf("%s%s",str1+1,str2+1)!=EOF){//从下标1的位置开始输入,有利于后续边界条件的处理 int n=strlen(str1+1);//求字符串长度 int m=strlen(str2+1); for(int i=0;i<=n;i++){//带等号,因为从下标1开始输入 for(int j=0;j<=m;j++){ if(i==0||j==0){//边界条件处理,str1或者str2其中一个字符串为空串,则他们的公共子串长度为0 dp[i][j]=0; continue; } //dp[i][j]分为两种情况,1--str1[i]和str2[j]相等,2--str1[i]和str2[j]不等 if(str1[i]==str2[j]){ //当str1[i]和str2[j]相等了,表示当前这两个子串末尾字符相同,则dp转化为str1的上个字符和str2的上个字符求公共子串长度+1 dp[i][j]=dp[i-1][j-1]+1; }else{ dp[i][j]=max(dp[i-1][j],dp[i][j-1]); //当str1[i]和str2[j]不相等 } } } cout<<dp[n][m]<<endl; } return 0; }
#include<iostream> #include<cstdio> #include<cstring> #include<string.h> using namespace std; const int MAXN = 101; int dp[MAXN][MAXN]; int main() { string str1,str2; while(cin>>str1>>str2) { //int len1 = strlen(str1); //int len2 = strlen(str2); int len1 = str1.size(); int len2 = str2.size(); for(int i=0; i<=len1; ++i) { dp[i][0] = 0; } for(int j=0; j<=len2; ++j) { dp[0][j] = 0; } for(int i=1; i<=len1; i++)//i和j的初始值应该为1 { for(int j=1; j<=len2; j++) { if(str1[i-1] == str2[j-1])//str数组里面相较于dp要全部前移一个 { dp[i][j] = dp[i-1][j-1] + 1; } else { dp[i][j] = max(dp[i-1][j],dp[i][j-1]); } } } printf("%d\n", dp[len1][len2]); } return 0; }最长公共子序列的裸题,注意dp数组和str数组相差1即可
#include <stdio.h> #include <string.h> int main() { char a[101],b[101]; int len1,len2,i,j; while(scanf("%s %s",a+1,b+1)!=EOF) { len1=strlen(a+1); len2=strlen(b+1); int dp[len1+1][len2+1]; for(i=0;i<=len1;i++) { for(j=0;j<=len2;j++) { if(i==0||j==0) dp[i][j]=0; else if(a[i]==b[j]) dp[i][j]=dp[i-1][j-1]+1; else dp[i][j]=dp[i-1][j]>dp[i][j-1]?dp[i-1][j]:dp[i][j-1]; } } printf("%d\n",dp[len1][len2]); } return 0; }
#include<iostream> #include<string> #include<algorithm> using namespace std; int main() { string str1, str2; while (cin>>str1>>str2) { int n = str1.size() + 1, m = str2.size() + 1; int** dp = new int* [n]; for (int i = 0; i < n; i++) { dp[i] = new int[m]; for (int j = 0; j < m; j++) { if (i == 0 || j == 0) { dp[i][j] = 0; continue; } if (str1[i - 1] == str2[j - 1]) dp[i][j] = dp[i - 1][j - 1] + 1; else dp[i][j] = max(dp[i][j - 1], dp[i - 1][j]); } } cout << dp[n - 1][m - 1] << endl; for (int k = 0; k < n; k++) delete[] dp[k]; delete[] dp; } return 0; }
#include<stdio.h> #include<string.h> int max(int a,int b){ return a>b?a:b; } int main(){ char s1[110],s2[110]; int dp[110][110]; while(~scanf("%s%s",s1,s2)){ int l1=strlen(s1); int l2=strlen(s2); for(int i=0;i<=l1;i++) dp[i][0]=0; for(int j=0;j<=l2;j++) dp[0][j]=0; for(int i=1;i<=l1;i++){ for(int j=1;j<=l2;j++){ if(s1[i-1]==s2[j-1]) dp[i][j]=dp[i-1][j-1]+1; else dp[i][j]=max(dp[i-1][j],dp[i][j-1]); } } printf("%d\n",dp[l1][l2]); } return 0; }
while True: try: string1,string2 = input(),input() result = [[0 for i in range(len(string2)+1)] for j in range(len(string1)+1)] #result[i][j]保存string1前i个子串和string2前j个子串的公共子序列 for i in range(1,len(string1)+1): for j in range(1,len(string2)+1): result[i][j] = max(result[i-1][j],result[i][j-1]) if string1[i-1]==string2[j-1]: result[i][j] = result[i-1][j-1]+1 #等于子串都减一的公共子序列长度加一 print(result[-1][-1]) except Exception: break
import java.util.Scanner; public class Main{ public static void main(String[] args){ Scanner in = new Scanner(System.in); while(in.hasNext()){ String a = in.next(); String b = in.next(); int m = a.length(); int n = b.length(); int[][] dp = new int[m+1][n+1]; for(int i=0;i<n+1;i++){ dp[0][i] = 0; } for(int i=0;i<m+1;i++) dp[i][0] = 0; for(int i=1;i<m+1;i++){ for(int j=1;j<n+1;j++){ if(a.charAt(i-1) == b.charAt(j-1)) dp[i][j] = dp[i-1][j-1]+1; else dp[i][j] = Math.max(dp[i][j-1], dp[i-1][j]); } } System.out.println(dp[m][n]); } } }
//最长公共子序列(LCS)问题,动态规划问题的一种,参考王道《机试指南》 #include <stdio.h> #include <string.h> #define N 101 //N是最大字符串长度 int dp[N][N]; /*dp[i][j]表示s1中前i个字符、s2中前j个字符组成的 两个字符串最长公共子序列长度*/ /*递推关系 dp[0][j]=0 dp[i][0]=0 dp[i][j]=dp[i-1][j-1]+1(如果s1[i-1]==s[j-1]的话) dp[i][j]=max{dp[i-1][j], dp[i][j-1]}(如果s1[i-1]!=s[j-1]的话) 前面括号里下标要-1是因为字符串下标从0开始,s1第1个字符是s[0] */ int Max(int a, int b)//返回a、b之中的较大值 { return a>b? a: b; } int main() { char s1[N], s2[N]; while(gets(s1)) { gets(s2); int len1=strlen(s1); int len2=strlen(s2); for(int i=0; i<N; i++)//先把dp数组清零 { for(int j=0; j<N; j++) { dp[i][j]=0; } } for(int i=0; i<N; i++)//dp[i][0]=0,dp[0][j]=0 { dp[i][0]=0; dp[0][i]=0; } for(int i=1; i<=len1; i++) { for(int j=1; j<=len2; j++) { if(s1[i-1]==s2[j-1]) dp[i][j]=dp[i-1][j-1]+1; else dp[i][j]=Max(dp[i-1][j], dp[i][j-1]); } } printf("%d\n", dp[len1][len2]); } return 0; }
#include <iostream> #include<vector> #include<string> using namespace std; int main() { //求最长公共子序列,这是一道简单的动态规划的题目,用二维数组来完成,dp[i][j]的含义为 //字符串s1[0]-s1[i-1]形成的字符串与字符串s2[0]-s2[j-1]形成的字符串的最长公共子序列的值 string str1,str2; cin>>str1>>str2; int m=str1.size(); int n=str2.size(); vector<vector<int>>dp(m+1,vector<int>(n+1,0));//定义dp数组的容量和初值 //找到状态转移方程 for(int i=1;i<m+1;i++){ for(int j=1;j<n+1;j++){ //这里选择一行一行地进行填充 if(str1[i-1]==str2[j-1]) dp[i][j]=dp[i-1][j-1]+1; else{ dp[i][j]=max(dp[i-1][j],dp[i][j-1]); } } } cout<<dp[m][n]<<endl; }
s1=input() s2=input() m,n=len(s1),len(s2) dp=[[0]*(m+1) for _ in range(n+1)] for i in range(1,n+1): for j in range(1,m+1): if s1[j-1]==s2[i-1]:dp[i][j]=dp[i-1][j-1]+1 else:dp[i][j]=max(dp[i-1][j],dp[i][j-1]) print(dp[-1][-1])
#include <cstdio> #include <cstring> #include <iostream> using namespace std; int main(){ char s1[101]; char s2[101]; int dp[101][101]; //存s1[i]和s2[j]结尾的的公共子序列的长度 while(scanf("%s %s",s1+1,s2+1) != EOF){ //从下标为1开始存 int n = strlen(s1+1); //C字符数组长度用strlen() int m = strlen(s2+1); for(int i = 0; i <= n; ++i){ for(int j = 0;j <= m; ++j){ if(i==0 || j==0){ dp[i][j] = 0; continue; } if(s1[i] == s2[j]){ dp[i][j] = dp[i-1][j-1] + 1; }else{ dp[i][j] = max(dp[i-1][j],dp[i][j-1]); } } } printf("%d\n",dp[n][m]); } return 0; }