codevs 1862 最长公共子序列(求最长公共子序列长度并统计最长公共子序列的个数)
字符序列的子序列是指从给定字符序列中随意地(不一定连续)去掉若干个字符(可能一个也不去掉)后所形成的字符序列。令给定的字符序列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的一个子序列。
对给定的两个字符序列,求出他们最长的公共子序列长度,以及最长公共子序列个数。
第1行为第1个字符序列,都是大写字母组成,以”.”结束。长度小于5000。
第2行为第2个字符序列,都是大写字母组成,以”.”结束,长度小于5000。
第1行输出上述两个最长公共子序列的长度。
第2行输出所有可能出现的最长公共子序列个数,答案可能很大,只要将答案对100,000,000求余即可。
ABCBDAB.
BACBBD.
4
7
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std; #define maxn 5010
#define MOD 100000000
char A[maxn],B[maxn],cur;
int f[][maxn], g[][maxn]; int main()
{
scanf("%s%s", A + , B + );
int na = strlen(A + ), nb = strlen(B + );
A[na--] = '\0'; B[nb--] = '\0'; cur=;
for(int i = ; i <= nb; i++) g[][i] = ;
g[][] = g[][] = ; for(int i = ; i <= na; i++)
{
cur ^= ;
for(int j = ; j <= nb; j++)
{
if(A[i] == B[j]) f[cur][j] =f[cur^][j-] + ;
else f[cur][j] = max(f[cur^][j], f[cur][j-]); g[cur][j] = ;
if(f[cur][j] == f[cur^][j]) g[cur][j] += g[cur^][j];
if(f[cur][j] == f[cur][j-]) g[cur][j] += g[cur][j-];
if(f[cur][j] == f[cur^][j] && f[cur][j] == f[cur][j-] && f[cur^][j-] == f[cur][j])
g[cur][j] -= g[cur^][j-];
if(A[i] == B[j] && f[cur][j] == f[cur^][j-] + ) g[cur][j] += g[cur^][j-];
if(g[cur][j] > MOD) g[cur][j] %= MOD;
if(g[cur][j] < ) g[cur][j] = (g[cur][j] % MOD) + MOD;
}
}
printf("%d\n%d\n", f[cur][nb], g[cur][nb]);
return ;
}
参考1:http://blog.csdn.net/moep0/article/details/52760974
参考2:http://blog.csdn.net/litble/article/details/67640655
算法分析:
第一个问题可以参考最长公共子序列原题的题解。

这里摘抄参考1里面的两段代码留存:
代码一:使用了滚动数组。
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <stack>
#include <vector>
#include <queue>
#include <cstring>
#include <string>
#include <map>
#include <set>
using namespace std; const int BufferSize = << ;
char buffer[BufferSize], *Head, *Tail;
inline char Getchar() {
if(Head == Tail) {
int l = fread(buffer, , BufferSize, stdin);
Tail = (Head = buffer) + l;
}
return *Head++;
}
int read() {
int x = , f = ; char c = Getchar();
while(!isdigit(c)){ if(c == '-') f = -; c = Getchar(); }
while(isdigit(c)){ x = x * + c - ''; c = Getchar(); }
return x * f;
} #define maxn 5010
#define MOD 100000000
char A[maxn], B[maxn], cur;
int f[][maxn], g[][maxn]; int main() {
scanf("%s%s", A + , B + );
int na = strlen(A + ), nb = strlen(B + );
A[na--] = '\0'; B[nb--] = '\0'; for(int i = ; i <= nb; i++) g[][i] = ; g[][] = g[][] = ;
for(int i = ; i <= na; i++) {
cur ^= ;
for(int j = ; j <= nb; j++) {
f[cur][j] = max(f[cur^][j], f[cur][j-]);
if(A[i] == B[j]) f[cur][j] = max(f[cur][j], f[cur^][j-] + );
g[cur][j] = ;
if(f[cur][j] == f[cur^][j]) g[cur][j] += g[cur^][j];
if(f[cur][j] == f[cur][j-]) g[cur][j] += g[cur][j-];
if(f[cur][j] == f[cur^][j] && f[cur][j] == f[cur][j-] && f[cur^][j-] == f[cur][j]) g[cur][j] -= g[cur^][j-];
if(A[i] == B[j] && f[cur][j] == f[cur^][j-] + ) g[cur][j] += g[cur^][j-];
if(g[cur][j] > MOD) g[cur][j] %= MOD;
if(g[cur][j] < ) g[cur][j] = (g[cur][j] % MOD) + MOD;
}
} printf("%d\n%d\n", f[cur][nb], g[cur][nb]); return ;
}
代码二:不使用滚动数组,假如测试数据较小,可以AC。
#include<iostream>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<cstdio>
#define mod 100000000
using namespace std;
string a,b;
int f[][],g[][];
int main(){
cin>>a>>b;
int l1=a.length()-,l2=b.length()-;
a=' '+a,b=' '+b;
for(int i=;i<=l1;i++)g[i][]=;
for(int i=;i<=l2;i++)g[][i]=;
for(int i=;i<=l1;i++)
for(int j=;j<=l2;j++)
{
if(a[i]==b[j])
{
f[i][j]=f[i-][j-]+;
g[i][j]=g[i-][j-];
if(f[i][j]==f[i][j-])g[i][j]=(g[i][j]+g[i][j-])%mod;
if(f[i][j]==f[i-][j])g[i][j]=(g[i][j]+g[i-][j])%mod;
}
else
{
f[i][j]=max(f[i-][j],f[i][j-]);
if(f[i][j]==f[i-][j])g[i][j]=(g[i][j]+g[i-][j])%mod;
if(f[i][j]==f[i][j-])g[i][j]=(g[i][j]+g[i][j-])%mod;
if(f[i][j]==f[i-][j-])g[i][j]-=g[i-][j-],g[i][j]=(g[i][j]+mod)%mod;
}
}
cout<<f[l1][l2]<<endl<<g[l1][l2]%mod;
return ;
}
codevs 1862 最长公共子序列(求最长公共子序列长度并统计最长公共子序列的个数)的更多相关文章
- 最长公共子序列(LCS)问题 Longest Common Subsequence 与最长公告字串 longest common substr
问题描述:字符序列的子序列是指从给定字符序列中随意地(不一定连续)去掉若干个字符(可能一个也不去掉)后所形成的字符序列.令给定的字符序列X=“x0,x1,…,xm-1”,序列Y=“y0,y1,…,yk ...
- POJ - 3415 Common Substrings(后缀数组求长度不小于 k 的公共子串的个数+单调栈优化)
Description A substring of a string T is defined as: T( i, k)= TiTi+1... Ti+k-1, 1≤ i≤ i+k-1≤| T|. G ...
- Frogger POJ - 2253(求两个石头之间”所有通路中最长边中“的最小边)
题意 题目主要说的是,有两只青蛙,在两个石头上,他们之间也有一些石头,一只青蛙要想到达另一只青蛙所在地方,必须跳在石头上.题目中给出了两只青蛙的初始位置,以及剩余石头的位置,问一只青蛙到达另一只青 ...
- POJ-Common Substrings(后缀数组-长度不小于 k 的公共子串的个数)
题意: 长度不小于 k 的公共子串的个数 分析: 基本思路是计算 A 的所有后缀和 B 的所有后缀之间的最长公共前缀的长度,把最长公共前缀长度不小于 k 的部分全部加起来. 先将两个字符串连起来,中间 ...
- POJ 3415 Common Substrings(长度不小于K的公共子串的个数+后缀数组+height数组分组思想+单调栈)
http://poj.org/problem?id=3415 题意:求长度不小于K的公共子串的个数. 思路:好题!!!拉丁字母让我Wa了好久!!单调栈又让我理解了好久!!太弱啊!! 最简单的就是暴力枚 ...
- POJ 3415 Common Substrings 【长度不小于 K 的公共子串的个数】
传送门:http://poj.org/problem?id=3415 题意:给定两个串,求长度不小于 k 的公共子串的个数 解题思路: 常用技巧,通过在中间添加特殊标记符连接两个串,把两个串的问题转换 ...
- Common Substrings POJ - 3415(长度不小于k的公共子串的个数)
题意: 给定两个字符串A 和 B, 求长度不小于 k 的公共子串的个数(可以相同) 分两部分求和sa[i-1] > len1 sa[i] < len1 和 sa[i-1] < ...
- poj 3415 后缀数组 两个字符串中长度不小于 k 的公共子串的个数
Common Substrings Time Limit: 5000MS Memory Limit: 65536K Total Submissions: 11469 Accepted: 379 ...
- 【POJ 3415】Common Substrings 长度不小于k的公共子串的个数
长度不小于k的公共子串的个数,论文里有题解,卡了一上午,因为sum没开long long!!! 没开long long毁一生again--- 以后应该早看POJ里的Discuss啊QAQ #inclu ...
随机推荐
- spring mvc 接受前台json @RequestBody json 属性 空 使用 JsonProperty spring mvc 获取json转乘bean
请给json序列序列化成的javabean 属性加上 @JsonProperty(value = "real_name") 否则 springmvc 可能接受不到数据 ja ...
- 洛谷 P1138 第k小整数
题目描述 现有n个正整数,n≤10000,要求出这n个正整数中的第k个最小整数(相同大小的整数只计算一次),k≤1000,正整数均小于30000. 输入输出格式 输入格式: 第一行为n和k; 第二行开 ...
- 奇怪吸引子---Bouali
奇怪吸引子是混沌学的重要组成理论,用于演化过程的终极状态,具有如下特征:终极性.稳定性.吸引性.吸引子是一个数学概念,描写运动的收敛类型.它是指这样的一个集合,当时间趋于无穷大时,在任何一个有界集上出 ...
- ds18b20驱动及应用程序
---------------------------------------------------------------------------------------------------- ...
- PHP优化---opcache的配置说明
[opcache] zend_extension = "G:/PHP/php-5.5.6-Win32-VC11-x64/ext/php_opcache.dll" ; Zend Op ...
- ES8新特性——ES8 was Released and here are its Main New Features
原文: https://hackernoon.com/es8-was-released-and-here-are-its-main-new-features-ee9c394adf66 -------- ...
- (转)NGUI中深度depth和z轴关系
先列出转载链接: http://game.ceeger.com/forum/read.php?tid=8917 转载原文: 问题源自一个帖子,因为上传的图比较多,就另开了这个贴写下自己的试验结果,原帖 ...
- [Algorithm] Binary tree: Level Order Traversal
function Node(val) { return { val, left: null, right: null }; } function Tree() { return { root: nul ...
- javascript捕获事件event
var e = e ? e : window.event; window.event ? window.event.cancelBubble = true : e.stopPropagation(); ...
- SVN 配置文件说明
svnserve是SVN自带的一个轻型服务器,客户端通过使用以svn://或svn+ssh://为前缀的URL来访问svnserve服务器,实现远程访问SVN版本库.svnserve可以通过配置文件来 ...