LCS问题
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了LCS问题相关的知识,希望对你有一定的参考价值。
最长公共子序列问题
核心代码:
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]); }
UVA10405 Longest Common Subsequence
模板题
代码:
#include<iostream> #include<vector> #include<cstdio> #include<cstring> #include<map> using namespace std; #define pb push_back #define mp make_pair #define se second #define fs first #define LL long long #define CLR(x) memset(x,0,sizeof x) #define MC(x,y) memcpy(x,y,sizeof(x)) #define SZ(x) ((int)(x).size()) #define FOR(it,c) for(__typeof((c).begin()) it=(c).begin();it!=(c).end();it++) #define lson l,m,rt<<1 #define rson m+1,r,rt<<1|1 typedef pair<int,int> P; const double eps=1e-9; const int maxn=200100; const int mod=1e9+7; const int INF=1e9; char s1[1050],s2[1050]; int dp[1050][1050]; int main() { while(gets(s1)&&gets(s2)) { int len1=strlen(s1); int len2=strlen(s2); CLR(dp); 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; }
UVA10252 Common Permutation
求一个最长子序列。使得子序列的全排列中有一个(可以不相同)是2个字符串的子序列.
仔细思考并不是LCS问题,直接模拟有多少个字符相同即可
代码:
#include<iostream> #include<vector> #include<cstdio> #include<cstring> #include<map> using namespace std; #define pb push_back #define mp make_pair #define se second #define fs first #define LL long long #define CLR(x) memset(x,0,sizeof x) #define MC(x,y) memcpy(x,y,sizeof(x)) #define SZ(x) ((int)(x).size()) #define FOR(it,c) for(__typeof((c).begin()) it=(c).begin();it!=(c).end();it++) #define lson l,m,rt<<1 #define rson m+1,r,rt<<1|1 typedef pair<int,int> P; const double eps=1e-9; const int maxn=200100; const int mod=1e9+7; const int INF=1e9; char s1[1050],s2[1050]; map<int,int> m,m2; int num[30]; int main() { while(gets(s1)&&gets(s2)) { m.clear();m2.clear(); int len1=strlen(s1); int len2=strlen(s2); for(int i=0;i<len1;i++) m[s1[i]-‘a‘]++; for(int i=0;i<len2;i++) m2[s2[i]-‘a‘]++; for(int i=0;i<26;i++) { num[i]=min(m[i],m2[i]); for(int j=0;j<num[i];j++) printf("%c",‘a‘+i); } printf("\n"); } return 0; }
UVA 531 Compromise
LCS问题+路径输出
路径输出标记每个位置的转移过程,然后递归输出
代码:
#include<iostream> #include<vector> #include<cstdio> #include<cstring> #include<map> using namespace std; #define pb push_back #define mp make_pair #define se second #define fs first #define LL long long #define CLR(x) memset(x,0,sizeof x) #define MC(x,y) memcpy(x,y,sizeof(x)) #define SZ(x) ((int)(x).size()) #define FOR(it,c) for(__typeof((c).begin()) it=(c).begin();it!=(c).end();it++) #define lson l,m,rt<<1 #define rson m+1,r,rt<<1|1 typedef pair<int,int> P; const double eps=1e-9; const int maxn=105; const int mod=1e9+7; const int INF=1e9; int dp[maxn][maxn]; int flag[maxn][maxn]; int l1,l2; string s1[maxn],s2[maxn]; void print_path(int x,int y) { if(x==0||y==0) return; if(flag[x][y]) { print_path(x-1,y-1); cout<<s1[x-1]; if(dp[x][y]!=dp[l1][l2]) cout<<" "; } else if(dp[x][y]==dp[x-1][y]) print_path(x-1,y); else print_path(x,y-1); } int main() { l1=l2=0; while(cin>>s1[l1++]){ while(cin>>s1[l1]&&s1[l1]!="#") l1++; while(cin>>s2[l2]&&s2[l2]!="#") l2++; CLR(dp);CLR(flag); 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; flag[i][j]=1; } else dp[i][j]=max(dp[i-1][j],dp[i][j-1]); } print_path(l1,l2); cout<<endl; l1=l2=0; } return 0; }
UVA10723 Cyborg Genes
LCS变种问题
仔细分析发现:最短目标字符串等于两个字符串长度的和减去最长公共子序列。dp[i][j]表示
那么数目的求和就等于最长公共子序列的路径组合数目。num[i][j]表示
首先初始化 num[0][i]=num[i][0]=1
1.s1[i]==s1[j] num[i][j]=num[i-1][j-1]
2.dp[i-1][j]>dp[i][j-1] num[i][j]=num[i-1][j]
3.dp[i-1][j]<dp[i][j-1] num[i][j]=num[i][j-1]
4.dp[i-1][j]==dp[i][j-1] num[i][j]=num[i-1][j]+num[i][j-1]
代码
#include<iostream> #include<vector> #include<cstdio> #include<cstring> using namespace std; #define pb push_back #define mp make_pair #define se second #define fs first #define LL long long #define CLR(x) memset(x,0,sizeof x) #define MC(x,y) memcpy(x,y,sizeof(x)) #define SZ(x) ((int)(x).size()) #define FOR(it,c) for(__typeof((c).begin()) it=(c).begin();it!=(c).end();it++) #define lson l,m,rt<<1 #define rson m+1,r,rt<<1|1 typedef pair<int,int> P; const double eps=1e-9; const int maxn=200100; const int mod=1e9+7; const int INF=1e9; int dp[50][50],num[50][50],len1,len2; char s1[50],s2[50]; int main() { int n,Case=1; scanf("%d",&n); getchar(); while(n--) { gets(s1);gets(s2); int len1=strlen(s1),len2=strlen(s2); CLR(dp);CLR(num); for(int i=0;i<50;i++) num[i][0]=num[0][i]=1; 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; num[i][j]=num[i-1][j-1]; } else if(dp[i-1][j]>dp[i][j-1]) { dp[i][j]=dp[i-1][j]; num[i][j]=num[i-1][j]; } else if(dp[i-1][j]<dp[i][j-1]) { dp[i][j]=dp[i][j-1]; num[i][j]=num[i][j-1]; } else { dp[i][j]=dp[i][j-1]; num[i][j]=num[i][j-1]+num[i-1][j]; } } printf("Case #%d:",Case++); printf(" %d %d\n",len1+len2-dp[len1][len2],num[len1][len2]); } }
以上是关于LCS问题的主要内容,如果未能解决你的问题,请参考以下文章