LCS
Posted kayiko
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了LCS相关的知识,希望对你有一定的参考价值。
做了几道LCS的题,总结一下
#include <cstdio> #include<iostream> #include<iomanip> #include<cstring> #include<sstream> #include<algorithm> #include<cstdio> #include<stdlib.h> #include<string> #include<map> #define _for(i,a,b) for(int i=a;i<=b;i++) using namespace std; typedef long long ll; const int MAXN=1e6+10; const int mod=998244353; const int INF=0x3f3f3f3f; char a[1010],b[1010]; int dp[1010][1010]; ll cnt[1000][1000]; int main() { int t; int dd=1; scanf("%d",&t); getchar(); while(t--) { gets(a); gets(b); int len1=strlen(a); int len2=strlen(b); memset(dp,0,sizeof(dp)); memset(cnt,0,sizeof(cnt)); for(int i=0;i<=len1;i++)cnt[i][0]=1; for(int i=0;i<=len2;i++)cnt[0][i]=1; for(int i=1;i<=len1;i++) { for(int j=1;j<=len2;j++) { if(a[i-1]==b[j-1]) { dp[i][j]=dp[i-1][j-1]+1; cnt[i][j]=cnt[i-1][j-1]; } else { if(dp[i-1][j]>dp[i][j-1]) { dp[i][j]=dp[i-1][j]; cnt[i][j]=cnt[i-1][j]; } else if(dp[i-1][j]<dp[i][j-1]) { dp[i][j]=dp[i][j-1]; cnt[i][j]=cnt[i][j-1]; } else { dp[i][j]=dp[i-1][j]; cnt[i][j]=cnt[i-1][j]+cnt[i][j-1]; } } } } printf("Case #%d: %d %lld ",dd++,len1+len2-dp[len1][len2],cnt[len1][len2]); } }
求全部两个串的全部的LCS
#include <iostream> #include <string> #include <vector> #include <set> #include <algorithm> using namespace std; string X = "ABCBDAB"; string Y = "BDCABA"; vector<vector<int>> table; // 动态规划表 set<string> setOfLCS; // set保存所有的LCS int max(int a, int b) { return (a>b)? a:b; } /** * 构造表,并返回X和Y的LCS的长度 */ int lcs(int m, int n) { // 表的大小为(m+1)*(n+1) table = vector<vector<int>>(m+1,vector<int>(n+1)); for(int i=0; i<m+1; ++i) { for(int j=0; j<n+1; ++j) { // 第一行和第一列置0 if (i == 0 || j == 0) table[i][j] = 0; else if(X[i-1] == Y[j-1]) table[i][j] = table[i-1][j-1] + 1; else table[i][j] = max(table[i-1][j], table[i][j-1]); } } return table[m][n]; } /** * 求出所有的最长公共子序列,并放入set中 */ void traceBack(int i, int j, string lcs_str, int lcs_len) { while (i>0 && j>0) { if (X[i-1] == Y[j-1]) { lcs_str.push_back(X[i-1]); --i; --j; } else { if (table[i-1][j] > table[i][j-1]) --i; else if (table[i-1][j] < table[i][j-1]) --j; else // 相等的情况 { traceBack(i-1, j, lcs_str, lcs_len); traceBack(i, j-1, lcs_str, lcs_len); return; } } } string str(lcs_str.rbegin(), lcs_str.rend()); // lcs_str逆序 if((int)str.size() == lcs_len) // 判断str的长度是否等于lcs_len setOfLCS.insert(str); } void print() { set<string>::iterator beg = setOfLCS.begin(); for( ; beg!=setOfLCS.end(); ++beg) cout << *beg << endl; } int main() { int m = X.length(); int n = Y.length(); int length = lcs(m, n); cout << "The length of LCS is " << length << endl; string str; traceBack(m, n, str, length); print(); getchar(); return 0;
TLE的
#include <cstdio> #include<iostream> #include<iomanip> #include<cstring> #include<sstream> #include<algorithm> #include<cstdio> #include<stdlib.h> #include<string> #include<map> #define _for(i,a,b) for(int i=a;i<=b;i++) using namespace std; typedef long long ll; const int MAXN=1e6+10; const int mod=1e8; const int INF=0x3f3f3f3f; int dp[6000][6000];//ABAAXGF AABXFGA int cnt[6000][6000]; int g[6000][6000]; char a[6000],b[6000]; int main() { scanf("%s%s",a,b); int len1=strlen(a); int len2=strlen(b); len1--,len2--; for(int i=0;i<=len1;i++)cnt[i][0]=1,g[i][0]=1; for(int i=0;i<=len2;i++)cnt[0][i]=1,g[0][i]=1; for(int i=1;i<=len1;i++) { for(int j=1;j<=len2;j++) { if(a[i-1]==b[j-1]) dp[i][j]=dp[i-1][j-1]+1,cnt[i][j]=cnt[i-1][j-1]; else { if(dp[i-1][j]>dp[i][j-1]) { dp[i][j]=dp[i-1][j],cnt[i][j]=cnt[i-1][j]; } else if(dp[i-1][j]<dp[i][j-1]) { dp[i][j]=dp[i][j-1],cnt[i][j]=cnt[i][j-1]; } else { dp[i][j]=dp[i-1][j],cnt[i][j]=cnt[i-1][j]+cnt[i][j-1]; } } if(dp[i][j]==dp[i-1][j]) (g[i][j]+=g[i-1][j])%mod; if(dp[i][j]==dp[i][j-1]) (g[i][j]+=g[i][j-1])%mod; if(a[i]==b[j]) if(dp[i][j]==dp[i-1][j-1]+1)(g[i][j]+=g[i-1][j-1])%mod; else if(dp[i][j]==dp[i-1][j-1])(g[i][j]-=g[i-1][j-1])%mod; } } cout<<dp[len1][len2]<<endl; cout<<g[len1][len2]%mod<<endl; }
AC的
#include <cstdio> #include<iostream> #include<iomanip> #include<cstring> #include<sstream> #include<algorithm> #include<cstdio> #include<stdlib.h> #include<string> #include<map> #define _for(i,a,b) for(int i=a;i<=b;i++) using namespace std; //typedef long long ll; int f[5005],last[5005],num[5005],ll[5005]; char s1[5005],s2[5005]; int mod=100000000; int n1,n2; int main() { int i,j,ans,bj,kl; scanf("%s",s1);scanf("%s",s2); n1=strlen(s1);n2=strlen(s2); n1--;n2--; for(i=0;i<=n2;i++)ll[i]=1; for(i=0;i<n1;i++){ for(j=0;j<n2;j++){ ll[0]=1;num[0]=1; if(s1[i]==s2[j]){ f[j+1]=last[j]+1;num[j+1]=ll[j]; num[j]=num[j]%mod; if(last[j+1]==f[j+1])num[j+1]+=ll[j+1]; num[j]=num[j]%mod; if(f[j]==f[j+1])num[j+1]+=num[j]; num[j]=num[j]%mod; } else { if(f[j]>last[j+1]){ f[j+1]=f[j];num[j+1]=num[j]; num[j]=num[j]%mod; } else if(f[j]<last[j+1]){ f[j+1]=last[j+1];num[j+1]=ll[j+1]; num[j]=num[j]%mod; } else { f[j+1]=f[j]; num[j+1]=num[j]+ll[j+1]; if(last[j]==f[j+1])num[j+1]-=ll[j]; num[j]=num[j]%mod; } } num[j]=num[j]%mod; } for(j=0;j<n2;j++){last[j+1]=f[j+1];ll[j+1]=num[j+1];} } printf("%d %d",f[n2],num[n2]); return 0; }
以上是关于LCS的主要内容,如果未能解决你的问题,请参考以下文章