【BZOJ2423】最长公共子序列(动态规划)

题面

BZOJ

洛谷

题解

今天考试的时候,神仙出题人\(fdf\)把这道题目作为一个二合一出了出来,我除了orz还是只会orz。

对于如何\(O(n^2)\)求解最长的长度是很简单的。

设\(f[i][j]\)表示第一个串匹配到了\(i\),第二个串匹配到了\(j\)的最大长度。

那么转移很显然,要么\(i\)向后挪动一位,要么\(j\)向后挪动一位,要么\(i,j\)匹配上了。

也就是\(f[i][j]=max(f[i-1][j],f[i][j-1],f[i-1][j-1]+1)\),最后一个转移当且仅当\(X[i]=Y[j]\)时才有。

考虑如何统计方案。显然是再记录一个数组\(g[i][j]\)表示到了\(f[i][j]\)时最长长度的方案数。

每次转移的时候如果长度一样则相加。

但是注意一个问题,当转移的时候,发现\(f[i-1][j],f[i][j-1],f[i-1][j-1]\)三者转移是相同的时候,

如果直接统计和的话,那么\(f[i-1][j-1]\)的方案会被重复计算两次,因此需要额外减去。

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
#define MOD 100000000
#define ll long long
#define MAX 5005
void add(int &x,int y){x+=y;if(x>=MOD)x-=MOD;}
int f[2][MAX],g[2][MAX],n,m;
int ans=0,sum=0;
char s[MAX],w[MAX];
int main()
{
scanf("%s%s",s+1,w+1);
n=strlen(s+1)-1;m=strlen(w+1)-1;
for(int i=0;i<=m;++i)g[0][i]=1;
for(int i=1,nw=1,pw=0;i<=n;++i,nw^=1,pw^=1)
{
memset(f[nw],0,sizeof(f[nw]));
memset(g[nw],0,sizeof(g[nw]));
g[nw][0]=1;
for(int j=1;j<=m;++j)
{
if(s[i]==w[j])f[nw][j]=f[pw][j-1]+1,g[nw][j]=g[pw][j-1];
else f[nw][j]=max(f[nw][j-1],f[pw][j]);
if(f[nw][j]==f[nw][j-1])add(g[nw][j],g[nw][j-1]);
if(f[nw][j]==f[pw][j])add(g[nw][j],g[pw][j]);
if(f[nw][j]==f[pw][j]&&f[nw][j]==f[nw][j-1]&&f[nw][j]==f[pw][j-1])add(g[nw][j],MOD-g[pw][j-1]);
}
}
printf("%d\n%d\n",f[n&1][m],g[n&1][m]);
return 0;
}

【BZOJ2423】最长公共子序列(动态规划)的更多相关文章

  1. 【ACM】最长公共子序列 - 动态规划

    最长公共子序列 时间限制:3000 ms  |  内存限制:65535 KB 难度:3   描述 咱们就不拐弯抹角了,如题,需要你做的就是写一个程序,得出最长公共子序列.tip:最长公共子序列也称作最 ...

  2. C++求解汉字字符串的最长公共子序列 动态规划

        近期,我在网上看了一些动态规划求字符串最长公共子序列的代码.可是无一例外都是处理英文字符串,当处理汉字字符串时.常常会出现乱码或者不对的情况. 我对代码进行了改动.使用wchar_t类型存储字 ...

  3. nyoj 36-最长公共子序列 (动态规划,DP, LCS)

    36-最长公共子序列 内存限制:64MB 时间限制:3000ms Special Judge: No accepted:18 submit:38 题目描述: 咱们就不拐弯抹角了,如题,需要你做的就是写 ...

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

    转自:http://segmentfault.com/blog/exploring/ LCS 问题描述 定义: 一个数列 S,如果分别是两个或多个已知数列的子序列,且是所有符合此条件序列中最长的,则 ...

  5. 动态规划求最长公共子序列(Longest Common Subsequence, LCS)

    1. 问题描述 子串应该比较好理解,至于什么是子序列,这里给出一个例子:有两个母串 cnblogs belong 比如序列bo, bg, lg在母串cnblogs与belong中都出现过并且出现顺序与 ...

  6. 动态规划(一)——最长公共子序列和最长公共子串

    注: 最长公共子序列采用动态规划解决,由于子问题重叠,故采用数组缓存结果,保存最佳取值方向.输出结果时,则自顶向下建立二叉树,自底向上输出,则这过程中没有分叉路,结果唯一. 最长公共子串采用参考串方式 ...

  7. 动态规划 - 最长公共子序列(LCS)

    最长公共子序列也是动态规划中的一个经典问题. 有两个字符串 S1 和 S2,求一个最长公共子串,即求字符串 S3,它同时为 S1 和 S2 的子串,且要求它的长度最长,并确定这个长度.这个问题被我们称 ...

  8. [BZOJ2423][HAOI2010]最长公共子序列

    [BZOJ2423][HAOI2010]最长公共子序列 试题描述 字符序列的子序列是指从给定字符序列中随意地(不一定连续)去掉若干个字符(可能一个也不去掉)后所形成的字符序列.令给定的字符序列X=“x ...

  9. 算法导论-动态规划(最长公共子序列问题LCS)-C++实现

    首先定义一个给定序列的子序列,就是将给定序列中零个或多个元素去掉之后得到的结果,其形式化定义如下:给定一个序列X = <x1,x2 ,..., xm>,另一个序列Z =<z1,z2  ...

随机推荐

  1. CentOS 7.X下 -- 配置nginx正向代理支持https

    环境说明: 本次测试使用的操作系统为:CentOS 7.2 x86 64位 最小化安装的操作系统,系统基础优化请参考:https://www.cnblogs.com/hei-ma/p/9506623. ...

  2. 如何在忘记mysql的登录密码时更改mysql登录的密码(window及linux)

    最近一直在边学习边开发java项目,理所当然的就少不了跟数据库打交道了,但是有时候就会脑子一短路,把mysql的登录密码给忘记了,这个时候我们又很急切的需要进到数据库中查看数据,那这个时候要怎么才能改 ...

  3. 信息提示 - bootStrap4常用CSS笔记

    .alert 基类 .alert-{success.info.warning.danger.primary.secondary.light.dark} 各种类型的配色样式 .fade..show 设置 ...

  4. egret性能优化总结

    ## 来自官方的优化建议 详见:http://edn.egret.com/cn/article/index/id/287 (1) 少使用Alpha混合. (2) 显式停止计时器,让它们准备好进行垃圾回 ...

  5. 2019网易笔试题C++--丰收

    题目描述 又到了丰收的季节,恰好小易去牛牛的果园里游玩. 牛牛常说他多整个果园的每个地方都了如指掌,小易不太相信,所以他想考考牛牛. 在果园里有N堆苹果,每堆苹果的数量为ai,小易希望知道从左往右数第 ...

  6. ABP.ModuleZero.Feature——特性管理

    原文地址:http://aspnetboilerplate.com/Pages/Documents/Feature-Management  (在翻译原文的基础上增补更多细节说明) 简介 在大多数SAA ...

  7. 用线性分类器实现预测鸢尾花的种类(python)

    这是个人学习时跑的代码,结果就不贴了,有需要的可以自己运行,仅供参考,有不知道的可以私下交流,有问题也可以联系我.当然了我也只能提供一点建议,毕竟我也只是初学者 第一个页面 # -*- coding: ...

  8. C++ 类的定义与实现

    摘自这篇博客https://blog.csdn.net/xulingxin/article/details/81335030   一."类" 的介绍     在C++中, 用 &q ...

  9. TeamWork#3,Week5,Performance Test of Crawlers

    爬虫总体性能不错,能完成基本的网络数据爬取,没有功能上的缺陷.下图为饿了么网站商户信息爬取结果及原网站信息. 大部分信息是正确的,但也有一些错误.比如下图,小渝馆家常菜和渝码头川菜位置爬取错了. 再比 ...

  10. 实验1 熟悉Linux开发环境 实验报告

    参见http://www.cnblogs.com/lhc-java/p/4970269.html