http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1006

参考博客 :http://blog.csdn.net/yysdsyl/article/details/4226630

引进一个二维数组c[][],用c[i][j]记录X[i]与Y[j] 的LCS 的长度,b[i][j]记录c[i][j]是通过哪一个子问题的值求得的,以决定搜索的方向。
我们是自底向上进行递推计算,那么在计算c[i,j]之前,c[i-1][j-1],c[i-1][j]与c[i][j-1]均已计算出来。此时我们根据X[i] = Y[j]还是X[i] != Y[j],就可以计算出c[i][j]。

计算 LCS 复杂度  O(n*m).由于每次调用至少向上或向左(或向上向左同时)移动一步,故最多调用(m + n)次就会遇到i = 0或j = 0的情况,此时开始返回。返回时与递归调用时方向相反,步数相同,故打印输出算法时间复杂度为Θ(m + n)。

打印序列,非递归。

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <set>
 5 #include <queue>
 6 #include <algorithm>
 7 #define MAXN 1111
 8 #define MAXM 222222
 9 #define INF 1000000000
10 using namespace std;
11
12 char s[MAXN],t[MAXN],res[MAXN];
13 int dp[MAXN][MAXN],flag[MAXN][MAXN];
14
15 void LCS(int n,int m)
16 {
17     memset(dp,0,sizeof(dp));
18     memset(flag,0,sizeof(flag));
19     for(int i=1;i<=n;i++)
20         for(int j=1;j<=m;j++)
21         {
22             if(s[i-1]==t[j-1])
23             {
24                 dp[i][j]=dp[i-1][j-1]+1;
25                 flag[i][j]=1;
26             }
27             else if(dp[i][j-1]>dp[i-1][j])
28             {
29                 dp[i][j]=dp[i][j-1];
30                 flag[i][j]=2;
31             }
32             else
33             {
34                 dp[i][j]=dp[i-1][j];
35                 flag[i][j]=3;
36             }
37         }
38     //printf("%d\n",dp[n][m]);
39 }
40
41 void getLCS(int n,int m)
42 {
43     int k=0;
44     while(n>0&&m>0)
45     {
46         if(flag[n][m]==1)
47         {
48             res[k++]=s[n-1];
49             n--;
50             m--;
51         }
52         else if(flag[n][m]==2) m--;
53         else if(flag[n][m]==3) n--;
54     }
55     for(int i=k-1;i>=0;i--)
56     {
57         printf("%c",res[i]);
58     }
59     printf("\n");
60 }
61
62 int main()
63 {
64     //freopen("a.txt","r",stdin);
65     scanf("%s %s",s,t);
66     //printf("%s %s\n",s,t);
67     int l1=strlen(s),l2=strlen(t);
68     LCS(l1,l2);
69     /*for(int i=0;i<=l1;i++)
70     {
71         for(int j=0;j<=l2;j++)
72             printf("%d ",flag[i][j]);
73         printf("\n");
74     }
75     printf("\n");*/
76     getLCS(l1,l2);
77     return 0;
78 }

View Code

递归

 1 #include<cstdio>
 2 #include<cstring>
 3 const int maxn=1111;
 4 int dp[maxn][maxn],flag[maxn][maxn];
 5 int n,m;
 6 char s[maxn],t[maxn];
 7
 8 void LCS(int n,int m)
 9 {
10     memset(dp,0,sizeof(dp));
11     memset(flag,0,sizeof(flag));
12     for(int i=0;i<n;i++)
13         for(int j=0;j<m;j++)
14         {
15             if(s[i]==t[j])
16             {
17                 dp[i+1][j+1]=dp[i][j]+1;
18                 flag[i+1][j+1]=1;
19             }
20             else if(dp[i+1][j]>dp[i][j+1])
21             {
22                 dp[i+1][j+1]=dp[i+1][j];
23                 flag[i+1][j+1]=2;
24             }
25             else
26             {
27                 dp[i+1][j+1]=dp[i][j+1];
28                 flag[i+1][j+1]=3;
29             }
30         }
31    // printf("%d\n",dp[n][m]);
32 }
33
34 void printLCS(int n,int m)
35 {
36     if(n==0||m==0) return;
37
38     if(flag[n][m]==1)
39     {
40         printLCS(n-1,m-1);
41         printf("%c",s[n-1]);
42     }
43     else if(flag[n][m]==2) printLCS(n,m-1);
44     else printLCS(n-1,m);
45 }
46 int main()
47 {
48     //freopen("a.txt","r",stdin);
49     scanf("%s %s",s,t);
50     int l1=strlen(s),l2=strlen(t);
51     LCS(l1,l2);
52     printLCS(l1,l2);
53     return 0;
54 }

View Code

下面这种是比较简洁的。去掉了标记数组。

 1 #include<string>
 2 #include<iostream>
 3 using namespace std;
 4 const int maxn = 1111;
 5
 6 int dp[maxn][maxn]={0};
 7 string a,b;
 8
 9 void LCS(int n,int m)
10 {
11     for(int i=1;i<=n;i++)
12         for(int j=1;j<=m;j++)
13         if(a[i-1]==b[j-1]) dp[i][j]=dp[i-1][j-1]+1;
14         else dp[i][j]=max(dp[i][j-1],dp[i-1][j]);
15 }
16
17 int main()
18 {
19     cin>>a>>b;
20     int l1=a.size(),l2=b.size();
21     LCS(l1,l2);
22     int len=dp[l1][l2];
23     string ans;
24     int i=l1,j=l2;
25     while(dp[i][j])
26     {
27         if(dp[i][j]==dp[i-1][j]) i--;
28         else if(dp[i][j]==dp[i][j-1]) j--;
29         else ans.push_back(a[i-1]),i--,j--;
30     }
31     for(int i=len-1;i>=0;i--)
32         cout<<ans[i];
33     return 0;
34 }

View Code

转载于:https://www.cnblogs.com/nowandforever/p/4429099.html

51 nod 1006 最长公共子序列Lcs相关推荐

  1. 【51NOD】1006 最长公共子序列Lcs(动态规划)

    给出两个字符串A B,求A与B的最长公共子序列(子序列不要求是连续的). 比如两个串为: abcicba abdkscab ab是两个串的子序列,abc也是,abca也是,其中abca是这两个字符串最 ...

  2. 51nod题解 1006 最长公共子序列LCS

    题目 #include<iostream> #include<cstring> #include<cstdio> using namespace std;char ...

  3. 51NOD 1006 最长公共子序列 Lcs 动态规划 DP 模板题 板子

    给出两个字符串A B,求A与B的最长公共子序列(子序列不要求是连续的). 比如两个串为: abcicba abdkscab ab是两个串的子序列,abc也是,abca也是,其中abca是这两个字符串最 ...

  4. 算法之最长公共子序列(LCS)问题

    算法课上老师留的作业,最长公共子序列LCS(Longest Common Subsequence)问题,首先看到这个问题感觉有点复杂,和最长公共子串不同,公共子序列并不要求元素相邻,看起来只有穷举才能 ...

  5. 动态规划算法解最长公共子序列LCS问题

    动态规划算法解LCS问题 作者 July 二零一零年十二月三十一日 本文参考:微软面试100题系列V0.1版第19.56题.算法导论.维基百科. 第一部分.什么是动态规划算法 ok,咱们先来了解下什么 ...

  6. 动态规划之最长公共子序列(LCS)

    最长公共子序列(LCS,Longest Common Subsequence).其定义是,一个序列 S ,如果分别是两个或多个已知序列的子序列,且是所有符合此条件序列中最长的,则 S 称为已知序列的最 ...

  7. 程序员编程艺术第十一章:最长公共子序列(LCS)问题

    程序员编程艺术第十一章:最长公共子序列(LCS)问题 0.前言 程序员编程艺术系列重新开始创作了(前十章,请参考程序员编程艺术第一~十章集锦与总结).回顾之前的前十章,有些代码是值得商榷的,因当时的代 ...

  8. 最长公共子序列php,动态规划(最长公共子序列LCS)

    概念 求解决策过程最优化的结果 (可能有多个) 把多阶段过程转化为一系列单阶段过程,利用各阶段之间的关系,逐个求解 计算过程中会把结果都记录下,最终结果在记录中找到. 举例 求两个字符串的最长公共子序 ...

  9. python实现求解最长公共子序列LCS问题

    在实现论文<Automatically Generating Models for Botnet Detection>论文的算法中,用到了一个The longest commom subs ...

最新文章

  1. 细节详解 | Bert,GPT,RNN及LSTM模型
  2. 开发者进阶宝典,HarmonyOS 职业认证全奉上
  3. [LeetCode]题解(python):140-Word Break II
  4. 蓝湖怎么切图标注_【蓝湖指北】你真的会切图吗?
  5. (六)docker-compose使用教程
  6. simpy练习案例(二):不直接控制流程,而是使用事件隐形控制流程 env.event()
  7. Java8中String.join方法,让我们的代码更优美
  8. 军哥lnmp一键安装包详解
  9. Futter基础第7篇: 实现底部导航
  10. Andersen Global宣布进驻印度市场
  11. 小程序 login获取出错: 40125, errmsg: invalid appSecret
  12. 全球及中国EDM放电加工机行业盈利投资分析及运营现状调研报告2021-2027年版
  13. 借助云开发实现小程序列表页(包含json数据的请求和解析)
  14. 200个句子搞定3500个高考词汇,究竟有多少词?
  15. 手撕生产者-消费者模式 | P问题、NP问题
  16. HCIP第十六天(VLAN IF接口,STP生成树协议,BPDU的配置)
  17. row format delimited fields terminated by ','
  18. python调用程序call_Python调用外部程序——os.system()和subprocess.call()
  19. 立创开源|USB示波器+信号发生器+USB存储 三合一
  20. 2021年 第十二届蓝桥杯第二期校内模拟赛题解(Java版)

热门文章

  1. LeetCode(349)——两个数组的交集(JavaScript)
  2. 灰度拉伸python_灰度变换之灰度线性拉伸(算法1)
  3. 淘宝直播应关注哪些方面?
  4. 职场上人和人的差距是怎样拉开的?
  5. 怎样能让电脑干干净净的没有各种弹窗广告?
  6. 最长递增子序列(力扣)图解
  7. mac下qt与mysql配置
  8. 操作系统的运行机制体系结构
  9. statusBar——状态栏
  10. 1045. 快速排序(25)-PAT乙级真题