LCS修改版(Longest Common Subsequence 最长公共子序列)

题目描述

作为一名情报局特工,Nova君(2号)有着特殊的传达情报的技巧。为了避免被窃取情报,每次传达时,他都会发出两句旁人看来意义不明话,实际上暗号已经暗含其中。解密的方法很简单,分别从两句话里删掉任意多个字母,使得两句话剩余的部分相同,通过一定的删除手法,可以让剩余的部分相同且长度最大,就得到了可能的暗号。暗号可能有多个,还要进行筛选,现在情报局人手不够,希望你能助一臂之力,筛选工作不用你完成,你只需计算出暗号长度以及个数即可。(注意,字母的位置也是暗号的重要信息,位置不同的字母组成的暗号不算同一种,详见样例)

输入

多组测试数据(组数小于20)

每组数据输入两行,分别为两个字符串(只含英文字母,无空格),每个字符串以"." 结束

输出

对于每组数据,输出两行,第一行为暗号的长度,第二行为暗号的个数(答案可能很大,对个数100000000求模)

输入样例

AAAA.
AA.

输出样例

2
6题目来源:http://biancheng.love/contest/17/problem/F/index最长公共子序列的实现可参考:http://www.cnblogs.com/huangxincheng/archive/2012/11/11/2764625.html和之前的不同在于需要计算出最长公共子序列一共有多少个!翻看不少博客很少有提到计算最长公共子序列的个数问题下面给出代码实现:
 1 #include <bits/stdc++.h>
 2 using namespace std;
 3
 4 const int m=100000000;//对m求模
 5 int f[2][5001]= {0},g[2][5001]= {0};
 6
 7 int main()
 8 {
 9     string s1,s2;
10     while(cin>>s1>>s2)
11     {
12         memset(f,0,sizeof(f));
13         memset(g,0,sizeof(g));
14         int len1=s1.size()-1,len2=s2.size()-1;//串s1,s2长度
15
16 for(int i=0; i<=len2; i++)
17 g[0][i]=1;
18     int k;
19     for(int i=1; i<=len1; i++)
20     {
21         k=i & 1;//与运算 当i是奇数时k=1,当i时偶数是k是0
22         memset(g[k],0,sizeof(g[k]));
23         memset(f[k],0,sizeof(f[k]));
24         g[k][0]=1;
25         g[!k][0]=1;
26         for(int j=1; j<=len2; j++)
27         {
28             if(s1[i-1]==s2[j-1])
29             {
30                 f[k][j]=f[!k][j-1]+1;
31                 g[k][j]=g[!k][j-1];
32                 g[k][j]%=m;
33                 if(f[k][j]==f[!k][j])
34                 {
35                     g[k][j]+=g[!k][j];
36                     g[k][j]%=m;
37                 }
38                 if(f[k][j-1]==f[k][j])
39                 {
40                     g[k][j]+=g[k][j-1];
41                     g[k][j]%=m;
42                 }
43             }
44             else
45             {
46                 if(f[!k][j]>f[k][j-1])
47                 {
48                     f[k][j]=f[!k][j];
49                     g[k][j]+=g[!k][j];
50                     g[k][j]%=m;
51                 }
52                 if(f[!k][j]<f[k][j-1])
53                 {
54                     f[k][j]=f[k][j-1];
55                     g[k][j]+=g[k][j-1];
56                     g[k][j]%=m;
57                 }
58                 if(f[!k][j]==f[k][j-1])
59                 {
60                     f[k][j]=f[!k][j];
61                     g[k][j]+=g[!k][j]+g[k][j-1];
62                  if(f[!k][j-1]==f[k][j])g[k][j]-=g[!k][j-1];
63                     g[k][j]=(g[k][j]+3*m)%m;
64                 }
65             }
66         }
67     }
68     cout<<f[k][len2]<<endl;
69     cout<<g[k][len2]<<endl;
70     }
71 }
				
时间: 2024-12-15 01:37:13

LCS修改版(Longest Common Subsequence 最长公共子序列)的相关文章

LCS(Longest Common Subsequence 最长公共子序列)

问题描述 最长公共子序列,英文缩写为LCS(Longest Com #include <bits/stdc++.h> const int MAX=1010; char x[MAX]; char y[MAX]; int DP[MAX][MAX]; int b[MAX][MAX]; using namespace std; int PRINT_LCS(int b[][MAX],char *x,int i,int j) { if(i==0||j==0) return 1; if(b[i][j]==1

POJ 1458 Common Subsequence(最长公共子序列LCS)

POJ1458 Common Subsequence(最长公共子序列LCS) http://poj.org/problem?id=1458 题意: 给你两个字符串, 要你求出两个字符串的最长公共子序列长度. 分析: 本题不用输出子序列,非常easy,直接处理就可以. 首先令dp[i][j]==x表示A串的前i个字符和B串的前j个字符的最长公共子序列长度为x. 初始化: dp全为0. 状态转移: IfA[i]==B[j] then dp[i][j]= dp[i-1][j-1]+1 else dp[

hdu 1159 Common Subsequence(最长公共子序列 DP)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1159 Common Subsequence Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 25416    Accepted Submission(s): 11276 Problem Description A subsequence of

POJ 1458 Common Subsequence 最长公共子序列

题目大意:求两个字符串的最长公共子序列 题目思路:dp[i][j] 表示第一个字符串前i位 和 第二个字符串前j位的最长公共子序列 #include<stdio.h> #include<string.h> #include<stdlib.h> #include<math.h> #include<iostream> #include<algorithm> #define INF 0x3f3f3f3f #define MAXSIZE 10

POJ 1458 Common Subsequence 最长公共子序列 LCS

LCS 1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 #include<iostream> 5 #define clc(a,b) memset(a,b,sizeof(a)) 6 #define LL long long 7 #include<cmath> 8 using namespace std; 9 int dp[1010][1010];//表示到i-1,j-1的

hdu 1159 Common Subsequence(最长公共子序列 动态规划)

Common Subsequence Problem Description A subsequence of a given sequence is the given sequence with some elements (possible none) left out. Given a sequence X = <x1, x2, ..., xm> another sequence Z = <z1, z2, ..., zk> is a subsequence of X if

hdu 1159 Common Subsequence(最长公共子序列)

#include<bits/stdc++.h> using namespace std; int dp[1024][1024]; int main() { int i,j; char s1[1024],s2[1024]; while(~scanf("%s %s",s1,s2)) { memset(dp,0,sizeof(dp)); int len1=strlen(s1); int len2=strlen(s2); for(i=0;i<len1;i++) { for(j

leetcode——Longest Common Prefix 最长公共前缀(AC)

Write a function to find the longest common prefix string amongst an array of strings. 其实做起来会感觉很简单,需要注意的是要考虑效率的问题,毕竟可能是很长的字符串数组,所以可以考虑选取所有字符串中最短的那个来首先进行比较,因为最长公共子串肯定不会大于其长度,这样避免了字符串之间长度差异很大造成的效率损失,然后每次比较之后最长公共子串的长度也永远不会大于最短的那个字符串,只会不变或减小,只要遍历字符串数组,挨个

最长公共子序列(LCS)问题 Longest Common Subsequence 与最长公告字串 longest common substr

问题描述:字符序列的子序列是指从给定字符序列中随意地(不一定连续)去掉若干个字符(可能一个也不去掉)后所形成的字符序列.令给定的字符序列X=“x0,x1,…,xm-1”,序列Y=“y0,y1,…,yk-1”是X的子序列,存在X的一个严格递增下标序列<i0,i1,…,ik-1>,使得对所有的j=0,1,…,k-1,有xij=yj.例如,X=“ABCBDAB”,Y=“BCDB”是X的一个子序列. 考虑最长公共子序列问题如何分解成子问题,设A=“a0,a1,…,am-1”,B=“b0,b1,…,bm