传送门

看到数据范围,显然 $n^2$ 的 $dp$...

设 $f[i][j]$ 表示 $A$ 串考虑了前 $i$ 位,$B$ 串考虑了前 $j$ 位,最优情况下的方案数

但是好像没法判断转移来的是否为最优方案?

所以再设 $g[i][j]$ 表示 $A$ 串考虑了前 $i$ 位,$B$ 串考虑了前 $j$ 位,最优情况下的匹配数

那么对于 $g$ 有转移,$g[i][j]=max(g[i-1][j],g[i][j-1])$,如果 $A[i]==B[j]$,那么 $g[i][j]=max(g[i][j],g[i-1][j-1]+1)$

然后考虑 $f$ 的转移

如果 $g[i-1][j]==g[i][j]$ 则 $f[i][j]+=f[i-1][j]$,如果 $g[i][j-1]==g[i][j]$ 则 $f[i][j]+=f[i][j-1]$,如果 $A[i]==B[j]$ 并且 $g[i][j]==g[i-1][j-1]$ 那么 $f[i][j]+=g[i-1][j-1]$

发现输出比答案大...

仔细分析发现如果 $g[i-1][j-1]==g[i][j]$,那么 $f[i-1][j-1]$ 的贡献会分别通过 $f[i][j-1],f[i-1][j]$ 转移到 $f[i][j]$ ,就被算了两次

所以如果 $g[i-1][j-1]==g[i][j]$ ,$f[i][j]$ 还要再减去 $f[i-1][j-1]$

最后,一定要滚动数组

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
using namespace std;
typedef long long ll;
inline int read()
{
int x=,f=; char ch=getchar();
while(ch<''||ch>'') { if(ch=='-') f=-; ch=getchar(); }
while(ch>=''&&ch<='') { x=(x<<)+(x<<)+(ch^); ch=getchar(); }
return x*f;
}
const int N=,mo=1e8;
inline int fk(int x) { return x>=mo ? x-mo : x; }
int n,m,f[][N],g[][N];
char a[N],b[N];
int main()
{
scanf("%s",a+); scanf("%s",b+);
n=strlen(a+)-,m=strlen(b+)-;
for(int i=;i<=m;i++) f[][i]=;
int cur=,pre;
for(int i=;i<=n;i++)
{
pre=cur; cur^=; f[cur][]=;
for(int j=;j<=m;j++) g[cur][j]=f[cur][j]=;
for(int j=;j<=m;j++)
{
if(a[i]==b[j]) g[cur][j]=g[pre][j-]+,f[cur][j]=f[pre][j-]; if(g[pre][j]>g[cur][j]) g[cur][j]=g[pre][j],f[cur][j]=f[pre][j];
else if(g[pre][j]==g[cur][j]) f[cur][j]=fk(f[cur][j]+f[pre][j]); if(g[cur][j-]>g[cur][j]) g[cur][j]=g[cur][j-],f[cur][j]=f[cur][j-];
else if(g[cur][j-]==g[cur][j]) f[cur][j]=fk(f[cur][j]+f[cur][j-]); if(g[cur][j]==g[pre][j-]) f[cur][j]=fk(f[cur][j]-f[pre][j-]+mo);
}
}
printf("%d\n%d\n",g[cur][m],f[cur][m]);
return ;
}

P2516 [HAOI2010]最长公共子序列的更多相关文章

  1. 2021.12.10 P2516 [HAOI2010]最长公共子序列(动态规划+滚动数组)

    2021.12.10 P2516 [HAOI2010]最长公共子序列(动态规划+滚动数组) https://www.luogu.com.cn/problem/P2516 题意: 给定字符串 \(S\) ...

  2. 洛谷P2516 [HAOI2010]最长公共子序列(LCS,最短路)

    洛谷题目传送门 一进来就看到一个多月前秒了此题的ysn和YCB%%% 最长公共子序列的\(O(n^2)\)的求解,Dalao们想必都很熟悉了吧!不过蒟蒻突然发现,用网格图貌似可以很轻松地理解这个东东? ...

  3. 洛谷 P2516 [HAOI2010]最长公共子序列

    题目传送门 解题思路: 第一问要求最长公共子序列,直接套模板就好了. 第二问要求数量,ans[i][j]表示第一个字符串前i个字符,第二个字符串前j个字符的最长公共子序列的数量 如果f[i][j]是由 ...

  4. P2516 [HAOI2010]最长公共子序列 题解(LCS)

    题目链接 最长公共子序列 解题思路 第一思路: 1.用\(length[i][j]\)表示\(a\)串的前\(i\)个字符与\(b\)串的前\(j\)个字符重叠的最长子串长度 2.用\(num[i][ ...

  5. luogu P2516 [HAOI2010]最长公共子序列

    传送门 首先那个\(O(n^2)\)的dp都会吧,不会自己找博客或者问别人,或是去做模板题(误) 对以下内容不理解的,强势推荐flash的博客 我们除了原来记录最长上升子序列的\(f_{i,j}\), ...

  6. 洛谷P2516 [HAOI2010]最长公共子序列

    题目描述 字符序列的子序列是指从给定字符序列中随意地(不一定连续)去掉若干个字符(可能一个也不去掉)后所形成的字符序列.令给定的字符序列X="x0,x1,-,xm-1",序列Y=& ...

  7. Luogu P2516 [HAOI2010]最长公共子序列 DP

    首先$LIS$显然:$f[i][j]=max(f[i][j-1],f[i-1][j],(a[i]==b[j])*f[i-1][j-1])$ 考虑如何转移数量: 首先,不管$a[i]$是否等于$b[j] ...

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

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

  9. 【BZOJ2423】[HAOI2010]最长公共子序列 DP

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

随机推荐

  1. linux安装配置Redis,Swoole扩展

    我是使用的是lnmp环境(php5.6.3) 一.安装redis数据库(参考w3c手册) 下载地址:http://redis.io/download 本教程使用的最新文档版本为 2.8.17,下载并安 ...

  2. 【javascript】生成二维码

    1 <!DOCTYPE html> 2 <html> 3 <head> 4 <meta charset="UTF-8"> 5 < ...

  3. memset设置最大值

    初始化为最大值 memset(mp,0x7f,sizeof(mp));

  4. Card Game Cheater

    Card Game Cheater Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others ...

  5. 在xml文件中使用该控件

    <yf.changsha.com.view.MyTextView android:layout_width="match_parent" android:layout_hei ...

  6. 使用mysql以及连接数据库

    MySQL Table of Contents 1. 安装与配置 2. 数据库与账户 3. 用户跟权限 4. 常用命令 5. 表的创建 6. 数据类型 7. 主键约束 8. 表的修改 9. 引擎(En ...

  7. Oracle dba角色和sysdba的区别

    如果用户需要远程sysdba的方式登陆,需要grant sysdba权限,登陆后以sys用户执行命令,需要验证密码文件. 密码文件如果是从12c之前的老版本同步过来,需要重建12c格式的密码文件. d ...

  8. legend2---开发常用语句

    legend2---开发常用语句 一.总结 一句话总结: 其实敲代码都是很类似的,比如ajax,模型等等,敲代码就是一个由生到熟的过程 1.ajax? $.post("{:url('broa ...

  9. Qt数据库之数据库连接池

     前面的章节里,我们使用了下面的函数创建和取得数据库连接: void createConnectionByName(const QString &connectionName) { QSql ...

  10. CentOS 6.7与CentOS 7.3内存查看命令free、top的差异对比

    https://www.centos.bz/2017/08/centos-6-7-centos-7-3-free-top/