BZOJ 2423 最长公共子序列
Description
Input
Output
Sample Input
BACBBD.
Sample Output
7
HINT
首先,求最长子序列就是一个经典的dp了。f[i][j]表示s1到第i位,s2到第j位的最长子序列,f[i][j]=max(f[i-1][j-1]+(s1[i]==s2[j]),f[i-1][j],f[i][j-1])。
麻烦的就是方案的转移,我们另g[i][j]表示s1到第i位,s2到第j位的最长子序列的方案数。考虑以下的几种情况:
1.s1[i]==s2[j],f[i][j]=f[i-1][j-1]+1。g[i][j]=g[i-1][j-1]+(f[i-1][j]==f[i][j])*g[i-1][j]+(f[i][j-1]==f[i][j])*g[i][j-1],三种情况互不包含(g[i-1][j-1]指s1[i]与s2[j]配对;若f[i-1][j]==f[i][j]的话,一定有s1[i-1]与s2[j]配对(否则f不会相等),累加g[i-1][j];同理g[i][j-1]指的是s1[i]与s2[j-1]配对),直接加即可。
2.否则的话,f[i][j]=max(f[i-1][j],f[i][j-1]),若两者相等,则g[i][j]=g[i-1][j]+g[i][j-1]-g[i-1][j-1],因为中间部分两者都计算了一遍,否则就加上大者即可。
由于O(n^2)的空间肯定是开不下的,所以我们要利用滚动数组。
#include<cstring>
#include<iostream>
#include<cstdio>
#include<cstdlib>
using namespace std; #define rhl (100000000)
#define maxn 5010
char s1[maxn],s2[maxn];
int f[][maxn],g[][maxn],n,m; inline void dp()
{
n = strlen(s1+),m = strlen(s2+);
s1[n--] = s2[m--] = ;
for (int i = ;i <= m;++i) g[][i] = ;
for (int i = ;i <= n;++i)
{
int p = i&,q = p^;
g[p][] = ;
for (int j = ;j <= m;++j)
{
g[p][j] = ;
if (s1[i] == s2[j])
{
f[p][j] = f[q][j-]+;
g[p][j] += g[q][j-];
if (f[q][j] == f[p][j]) g[p][j] += g[q][j];
if (f[p][j-] == f[p][j]) g[p][j] += g[p][j-];
}
else
{
f[p][j] = max(f[p][j-],f[q][j]);
if (f[p][j-] > f[q][j]) g[p][j] = g[p][j-];
else if (f[q][j] > f[p][j-]) g[p][j] = g[q][j];
else
{
g[p][j] = g[q][j]+g[p][j-];
if (f[q][j-] == f[p][j]) g[p][j] -= g[q][j-];
}
}
while (g[p][j] >= rhl) g[p][j] -= rhl;
while (g[p][j] < ) g[p][j] += rhl;
}
}
printf("%d\n%d",f[n&][m],g[n&][m]);
} int main()
{
freopen("2423.in","r",stdin);
freopen("2423.out","w",stdout);
scanf("%s%s",s1+,s2+);
dp();
fclose(stdin); fclose(stdout);
return ;
}
BZOJ 2423 最长公共子序列的更多相关文章
- bzoj:2423: [HAOI2010]最长公共子序列
Description 字符序列的子序列是指从给定字符序列中随意地(不一定连续)去掉若干个字符(可能一个也不去掉)后所形成的字符序列.令给定的字符序列X=“x0,x1,…,xm-1”,序列Y=“y0, ...
- bzoj 2423: [HAOI2010]最长公共子序列【dp+计数】
设f[i][j]为a序列前i个字符和b序列前j个字符的最长公共子序列,转移很好说就是f[i][j]=max(f[i-1][j],f[i][j-1],f[i-1][j-1]+(a[i]==b[j])) ...
- BZOJ 3304: [Shoi2005]带限制的最长公共子序列( LCS )
求个LCS, 只是有了限制, 多加一维表示匹配到z串的第几个, 然后用滚动数组 ------------------------------------------------------------ ...
- 【BZOJ2423】最长公共子序列(动态规划)
[BZOJ2423]最长公共子序列(动态规划) 题面 BZOJ 洛谷 题解 今天考试的时候,神仙出题人\(fdf\)把这道题目作为一个二合一出了出来,我除了orz还是只会orz. 对于如何\(O(n^ ...
- 【bzoj2423】最长公共子序列[HAOI2010](dp)
题目传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=2423 题目大意:求两个字符串的最长公共子序列长度和最长公共子序列个数. 这道题的话,对于 ...
- 用python实现最长公共子序列算法(找到所有最长公共子串)
软件安全的一个小实验,正好复习一下LCS的写法. 实现LCS的算法和算法导论上的方式基本一致,都是先建好两个表,一个存储在(i,j)处当前最长公共子序列长度,另一个存储在(i,j)处的回溯方向. 相对 ...
- 动态规划之最长公共子序列(LCS)
转自:http://segmentfault.com/blog/exploring/ LCS 问题描述 定义: 一个数列 S,如果分别是两个或多个已知数列的子序列,且是所有符合此条件序列中最长的,则 ...
- [Data Structure] LCSs——最长公共子序列和最长公共子串
1. 什么是 LCSs? 什么是 LCSs? 好多博友看到这几个字母可能比较困惑,因为这是我自己对两个常见问题的统称,它们分别为最长公共子序列问题(Longest-Common-Subsequence ...
- 动态规划求最长公共子序列(Longest Common Subsequence, LCS)
1. 问题描述 子串应该比较好理解,至于什么是子序列,这里给出一个例子:有两个母串 cnblogs belong 比如序列bo, bg, lg在母串cnblogs与belong中都出现过并且出现顺序与 ...
随机推荐
- UVA 10627 - Infinite Race(数论)
UVA 10627 - Infinite Race option=com_onlinejudge&Itemid=8&page=show_problem&category=516 ...
- good page
http://www.cnblogs.com/zrtqsk/category/540486.html
- SSD -----TLC MLC SLC
SLC缓存什么鬼?TLC评测造假要持续多久 2016.5.5来源:中关村在线 TLC的廉价真的将SSD引入了全面普及的高速公路上,谈到TLC我们更多的理解是TLC的P/E(Program/Erase ...
- Qt 学习之路:文本文件读写
上一章我们介绍了有关二进制文件的读写.二进制文件比较小巧,却不是人可读的格式.而文本文件是一种人可读的文件.为了操作这种文件,我们需要使用QTextStream类.QTextStream和QDataS ...
- IOS--实现滤镜效果的四种方式
IOS–实现滤镜效果 demo地址: https://github.com/AbeDay/ios–.git 使用CIFilter来完成IOS中滤镜效果 在IOS中可以使用系统自带的方法来达到路径效果: ...
- centos6.5 安装
导系统,进入rescue模式,在提示符下输入grub,进入grub提示符.(不管用什么方法,能进入grub就行)root(hd?,?) //前一个问号是你第几块硬盘,后一个是LINUX所在的第几个分区 ...
- Android Studio快速生成get set等函数
方式一:Code-->Generate 方式二:通过快捷键Alt+Insert
- new Integer(1)和Integer.valueOf(1)的区别
java.lang包中的Integer类是我们比较常用的类,比如以下代码: Integer a=new Integer(1) Integer a=Integer.valueOf(1); 两个都是得到一 ...
- CSS美化 input type=file 兼容各个浏览器(转)
HTML代码: <FORM> <A class=btn_addPic href="javascript:void(0);"><SPAN>< ...
- 提供他人class文件
1.考虑的问题,提供的文件是否依赖于其他jar包. 例如:解析html简历时,依赖于Jsoup包.