最长公共子序列lcs
Posted xiongtao
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了最长公共子序列lcs相关的知识,希望对你有一定的参考价值。
本来想总结的,发现总结不来,不会组织语言,就水水的贴一下大佬总结的博客:https://blog.csdn.net/so_geili/article/details/53737001
一道简单的模板题:http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1006
题目意思就是求两个字符串的任意一个最大公共子序列
代码
#include<iostream> #include<algorithm> #include<cstdio> #include<cstring> using namespace std; char a[1005],b[1005]; int dp[1005][1005],r[1005][1005]; void dplcs(int la,int lb) { for(int i=0;i<=la;i++) dp[i][0]=0; for(int j=1;j<=lb;j++) dp[0][j]=0; for(int i=1;i<=la;i++) for(int j=1;j<=lb;j++) { if(a[i-1]==b[j-1])//从对角线过来的 { dp[i][j]=dp[i-1][j-1]+1; r[i][j]=1; } else if(dp[i-1][j]>=dp[i][j-1])//从上面过来的 { dp[i][j]=dp[i-1][j]; r[i][j]=3; } else//从左边过来的 { dp[i][j]=dp[i][j-1]; r[i][j]=2; } } } void printlcs(int la,int lb)//递归实现 { if(la==0||lb==0) return ; if(r[la][lb]==1) { printlcs(la-1,lb-1); cout<<a[la-1];//反向输出 } else if(r[la][lb]==3) printlcs(la-1,lb); else printlcs(la,lb-1); } int main() { cin>>a>>b; memset(r,0,sizeof(r)); int la=strlen(a); int lb=strlen(b); dplcs(la,lb); printlcs(la,lb); cout<<endl; return 0; }
第二题:https://vjudge.net/contest/236677#problem/B
题目意思反过来的,给你dp矩阵,求任意符合的两个字符串
思路:先固定a,字符串很小,所以直接赋"abcd...",根据dp矩阵来确定b,但有一个问题就是b[j]可能已经确定了,那么只能讲对应的a[i]改成b[j],有连锁反应,所以要
遍历此时的a,b字符串,将等于a[i]都改成b[j]。在最后将没有确定的b[j]都随意赋没有出现的字母就行了
#include<algorithm> #include<cstdio> #include<cstring> using namespace std; int dp[105][105]; char a[105],b[105]; bool vis_b[105];//b是否确定 int main() { int n,m; while(cin>>n>>m) { memset(vis_b,0,sizeof(vis_b)); for(int i=0;i<=n;i++) for(int j=0;j<=m;j++) cin>>dp[i][j]; for(int i=0;i<n;i++) a[i]=‘a‘+i;//令a为abcd... a[n]=b[m]=‘