为了账号安全,请及时绑定邮箱和手机立即绑定

动态规划——最长公共子序列(算法设计课题)

标签:
算法

问题描述:

若给定序列X={x1,x2,…,xm},则另一序列Z={z1,z2,…,zk},是X的子序列是指存在一个严格递增下标序列{i1,i2,…,ik}使得对于所有j=1,2,…,k有:zj=xij。例如,序列Z={B,C,D,B}

是序列X={A,B,C,B,D,A,B}的子序列,相应的递增下标序列为{2,3,5,7}。

给定2个序列X和Y,当另一序列Z既是X的子序列又是Y的子序列时,称Z是序列X和Y的公共子序列。

给定2个序列X={x1,x2,…,xm}和Y={y1,y2,…,yn},找出X和Y的最长公共子序列。

解题思路:

设序列X={x1,x2,…,xm}和Y={y1,y2,…,yn}的最长公共子序列为Z={z1,z2,…,zk} ,则
(1)若xm=yn,则zk=xm=yn,且zk-1是xm-1和yn-1的最长公共子序列。
(2)若xm≠yn且zk≠xm,则Z是xm-1和Y的最长公共子序列。
(3)若xm≠yn且zk≠yn,则Z是X和yn-1的最长公共子序列。

https://img1.sycdn.imooc.com//5b52b3220001c39c06440480.jpg


由于在所考虑的子问题空间中,总共有θ(mn)个不同的子问题,因此,用动态规划算法自底向上地计算最优值能提高算法的效率。


#include<stdio.h>#include<string.h>#define MAXLEN 100void LCSLength(char *x, char *y, int m, int n, int c[][MAXLEN], int b[][MAXLEN]){int i, j;for(i = 0; i <= m; i++)c[i][0] = 0;for(j = 1; j <= n; j++)c[0][j] = 0;for(i = 1; i<= m; i++){for(j = 1; j <= n; j++){if(x[i-1] == y[j-1]){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;}}}}void PrintLCS(int b[][MAXLEN],char *x,int i,int j){if(i==0||j==0)return;if(b[i][j]==1){PrintLCS(b,x,i-1,j-1);printf("%c",x[i-1]);		}else if(b[i][j]==2)PrintLCS(b,x,i-1,j);elsePrintLCS(b,x,i,j-1);}int main(int argc, char **argv){char x[MAXLEN];char y[MAXLEN];int b[MAXLEN][MAXLEN];int c[MAXLEN][MAXLEN];int m,n;while(-1){gets(x);gets(y);m=strlen(x);n=strlen(y);LCSLength(x,y,m,n,c,b);PrintLCS(b,x,m,n);printf("\n");}return 0;}


点击查看更多内容
TA 点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
  • 推荐
  • 评论
  • 收藏
  • 共同学习,写下你的评论
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消