动态规划之最长公共子序列
来源:互联网 发布:淘宝客服搞笑评价回复 编辑:程序博客网 时间:2024/05/04 13:35
背景:
对于两个给定的序列X ={A,B,C,D,A,B},Y={B,D,C,A,B,A},例如{B,C,D,A}是他们的最长公共子序列,但并不是唯一的最长公共子序列。比如说{B,D,A,B}
但该动态规划算法着重于分析如何求出一个最长公共子序列,至于求出所有最长公共子序列,或者是多个给定的序列求最长公共子序列还需有待研究!
分析:
动态规划算法的特征总是先由大到小的分析出最优子结构,再通过递归自下到上的得出所得解。
假设序列X={x1,x2,........xm}和Y={y1,y2,........yn}的最长公共子序列为Z={z1,z2,....zk}
从整体开始分析,即从尾部往前推
1.若xm=yn,则zk=xm=yn,且Z k-1是Xm-1和Yn-1的最长公共子序列,这样便降低问题规模,达到了用递归求解的目的
2.若xm!=yn且zk!=xm,则Z是Xm-1和Y n的最长公共子序列
3.若xm!=yn且zk!=yn,则Z是Xm和Y n-1的最长公共子序列
建立问题模型:
1.假设用c[i][j]表示Xi和Yj的最长公共子序列的长度,Xi={x1,x2.....xi} Yj={y1,y2......yj}
2.边界条件考虑,i=0或者j=0时,c[i][j]=0
所以
0 i=0或者j=0
c[i][j]= c[i-1][j-1]+1 i,j>0;xi=yj
Max{c[i][j-1],c[i-1][j]} i,j>0;xi!=yj
性能分析:
每一次x[i]和y[j]的比较就降低一次问题规模,总共比较了mxn次,所以时间复杂度为O(nm).。相对于一般的穷举算法,即列举出X 的所有子序列共有2的n次方种,和Y序列一个个的进行比对,时间复杂度为O(2n),相比复杂度从指数规模降低到了平方级规模。
#include<iostream>using namespace std;#define MAX 20void LCSLength(int m,int n,char *x,char *y,int c[][MAX],int b[][MAX]){int i,j;for( i=1;i<=m;i++) c[i][0]=0; //只有x或y的情况下,c[i][j]都为0for(i=1;i<=n;i++) c[0][i]=0; for( i=1;i<=m;i++)for(j=1;j<=n;j++){if(x[i]==y[j]){c[i][j]=c[i-1][j-1]+1; //加上这个位置的字符b[i][j]=1;}else if(c[i-1][j]>=c[i][j-1]){c[i][j]=c[i-1][j];b[i][j]=2;}else {c[i][j]=c[i][j-1];b[i][j]=3;}cout<<"c["<<i<<"]["<<j<<"]"<<c[i][j]<<" b["<<i<<"]["<<j<<"]"<<b[i][j]<<endl;}}void LCS(int i,int j,char *x,int b[][MAX]){if(i==0||j==0)return ;if(b[i][j]==1){LCS(i-1,j-1,x,b);cout<<x[i];}else if(b[i][j]==2)LCS(i-1,j,x,b);else LCS(i,j-1,x,b);}void InitSequence(int n,char *s){cout<<"请输入"<<n<<"个字符序列"<<endl;for(int i=1;i<=n;i++)cin>>s[i];}int main(){int m,n;char x[MAX],y[MAX];int c[MAX][MAX],b[MAX][MAX];while(scanf("%d %d",&m,&n)==2){InitSequence(m,x);InitSequence(n,y);LCSLength(m,n,x,y,c,b);LCS(m,n,x,b);}return 0;}
- 动态规划之最长公共子序列
- 动态规划之最长公共子序列
- 动态规划之最长公共子序列
- 动态规划之最长公共子序列
- 动态规划之最长公共子序列
- 动态规划之最长公共子序列
- 动态规划之最长公共子序列
- 动态规划之最长公共子序列
- 动态规划之最长公共子序列
- 动态规划之最长公共子序列
- 动态规划之最长公共子序列
- 动态规划之最长公共子序列
- 动态规划之最长公共子序列
- 动态规划之最长公共子序列
- 动态规划之最长公共子序列
- 动态规划之最长公共子序列
- 动态规划之最长公共子序列
- 动态规划之最长公共子序列
- 算法--生成1~n的排列
- [转]ROC曲线-阈值评价标准
- Android权限大全
- c++模板元编程三:循环展开
- Xcode个人常用快捷键
- 动态规划之最长公共子序列
- rnnlib process image
- python包管理工具总结
- ZSTU OJ 4189 逻辑运算(逆波兰式)
- “我的测试哲学”
- 在Android里显示网页的多种方式
- 第五周程序阅读四
- appstore中关于idfa的选项都是什么意思
- cursor :ponter;