【BZOJ2423】最长公共子序列(动态规划)
【BZOJ2423】最长公共子序列(动态规划)
题面
题解
今天考试的时候,神仙出题人\(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】最长公共子序列(动态规划)的更多相关文章
- 【ACM】最长公共子序列 - 动态规划
最长公共子序列 时间限制:3000 ms | 内存限制:65535 KB 难度:3 描述 咱们就不拐弯抹角了,如题,需要你做的就是写一个程序,得出最长公共子序列.tip:最长公共子序列也称作最 ...
- C++求解汉字字符串的最长公共子序列 动态规划
近期,我在网上看了一些动态规划求字符串最长公共子序列的代码.可是无一例外都是处理英文字符串,当处理汉字字符串时.常常会出现乱码或者不对的情况. 我对代码进行了改动.使用wchar_t类型存储字 ...
- nyoj 36-最长公共子序列 (动态规划,DP, LCS)
36-最长公共子序列 内存限制:64MB 时间限制:3000ms Special Judge: No accepted:18 submit:38 题目描述: 咱们就不拐弯抹角了,如题,需要你做的就是写 ...
- 动态规划之最长公共子序列(LCS)
转自:http://segmentfault.com/blog/exploring/ LCS 问题描述 定义: 一个数列 S,如果分别是两个或多个已知数列的子序列,且是所有符合此条件序列中最长的,则 ...
- 动态规划求最长公共子序列(Longest Common Subsequence, LCS)
1. 问题描述 子串应该比较好理解,至于什么是子序列,这里给出一个例子:有两个母串 cnblogs belong 比如序列bo, bg, lg在母串cnblogs与belong中都出现过并且出现顺序与 ...
- 动态规划(一)——最长公共子序列和最长公共子串
注: 最长公共子序列采用动态规划解决,由于子问题重叠,故采用数组缓存结果,保存最佳取值方向.输出结果时,则自顶向下建立二叉树,自底向上输出,则这过程中没有分叉路,结果唯一. 最长公共子串采用参考串方式 ...
- 动态规划 - 最长公共子序列(LCS)
最长公共子序列也是动态规划中的一个经典问题. 有两个字符串 S1 和 S2,求一个最长公共子串,即求字符串 S3,它同时为 S1 和 S2 的子串,且要求它的长度最长,并确定这个长度.这个问题被我们称 ...
- [BZOJ2423][HAOI2010]最长公共子序列
[BZOJ2423][HAOI2010]最长公共子序列 试题描述 字符序列的子序列是指从给定字符序列中随意地(不一定连续)去掉若干个字符(可能一个也不去掉)后所形成的字符序列.令给定的字符序列X=“x ...
- 算法导论-动态规划(最长公共子序列问题LCS)-C++实现
首先定义一个给定序列的子序列,就是将给定序列中零个或多个元素去掉之后得到的结果,其形式化定义如下:给定一个序列X = <x1,x2 ,..., xm>,另一个序列Z =<z1,z2 ...
随机推荐
- 【Unity Shader】(七) ------ 复杂的光照(下)
笔者使用的是 Unity 2018.2.0f2 + VS2017,建议读者使用与 Unity 2018 相近的版本,避免一些因为版本不一致而出现的问题. [Unity Sha ...
- 《杜增强讲Unity之Tanks坦克大战》2-场景设置
2 场景设置 2.1 本节效果预览 2.2 项目目录设置 点击Project面板的Create按钮,在根目录下面新建wm文件夹 Wm文件夹用于存放我们自己生成的Prefab和脚本等其他资源, ...
- 树莓派操控SG90舵机
目录 舵机接线 PWM介绍 使用PWM控制舵机 这里使用树莓派来操作sg90的舵机.先看一下这个舵机的样子: 这就是传说中的SG90舵机啦,转角是0-180. SG90舵机接线: SG90舵机有三条线 ...
- 教你如何编写、保存与运行 Python 程序
第一步 接下来我们将看见如何在 Python 中运行一个传统的“Hello World”程序.Python教程本章将会教你如何编写.保存与运行 Python 程序. 通过 Python 来运行的你的程 ...
- CF 675E Trains and Statistic
草稿和一些题解而已 因为指针太恶心了 所以query决定还是要试试自己yy一下 #include<cstdio> #include<cstring> #include<i ...
- POJ 3468 A Simple Problem with Integers(分块入门)
题目链接:http://poj.org/problem?id=3468 A Simple Problem with Integers Time Limit: 5000MS Memory Limit ...
- import 导入包的特别用法总结
指定别名 可以为包指定一个别名,以便记忆或提高输入效率 如 import str "strings" 在使用的时候可以直接使用别名,如原先要写成strings.Contains,现 ...
- 使用Python 统计nginx日志前十ip访问量并以柱状图显示
脚本内容: import matplotlib.pyplot as plt # nginx_file = '10.6.11.91_access.log-2018-12-27' ip = {} #筛选n ...
- C++多态深入分析!
以下分析是基于VS2010的.以后会使用G++分析看看G++如何处理多态! // polymorphic_test.cpp : 定义控制台应用程序的入口点. // /** 特别注意:实现C++多态,除 ...
- 调试存储过程:ORA-0131 Insufficient privileges
http://www.cnblogs.com/empty01/p/5568250.html