P2516 [HAOI2010]最长公共子序列
看到数据范围,显然 $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]最长公共子序列的更多相关文章
- 2021.12.10 P2516 [HAOI2010]最长公共子序列(动态规划+滚动数组)
2021.12.10 P2516 [HAOI2010]最长公共子序列(动态规划+滚动数组) https://www.luogu.com.cn/problem/P2516 题意: 给定字符串 \(S\) ...
- 洛谷P2516 [HAOI2010]最长公共子序列(LCS,最短路)
洛谷题目传送门 一进来就看到一个多月前秒了此题的ysn和YCB%%% 最长公共子序列的\(O(n^2)\)的求解,Dalao们想必都很熟悉了吧!不过蒟蒻突然发现,用网格图貌似可以很轻松地理解这个东东? ...
- 洛谷 P2516 [HAOI2010]最长公共子序列
题目传送门 解题思路: 第一问要求最长公共子序列,直接套模板就好了. 第二问要求数量,ans[i][j]表示第一个字符串前i个字符,第二个字符串前j个字符的最长公共子序列的数量 如果f[i][j]是由 ...
- P2516 [HAOI2010]最长公共子序列 题解(LCS)
题目链接 最长公共子序列 解题思路 第一思路: 1.用\(length[i][j]\)表示\(a\)串的前\(i\)个字符与\(b\)串的前\(j\)个字符重叠的最长子串长度 2.用\(num[i][ ...
- luogu P2516 [HAOI2010]最长公共子序列
传送门 首先那个\(O(n^2)\)的dp都会吧,不会自己找博客或者问别人,或是去做模板题(误) 对以下内容不理解的,强势推荐flash的博客 我们除了原来记录最长上升子序列的\(f_{i,j}\), ...
- 洛谷P2516 [HAOI2010]最长公共子序列
题目描述 字符序列的子序列是指从给定字符序列中随意地(不一定连续)去掉若干个字符(可能一个也不去掉)后所形成的字符序列.令给定的字符序列X="x0,x1,-,xm-1",序列Y=& ...
- 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] ...
- [BZOJ2423][HAOI2010]最长公共子序列
[BZOJ2423][HAOI2010]最长公共子序列 试题描述 字符序列的子序列是指从给定字符序列中随意地(不一定连续)去掉若干个字符(可能一个也不去掉)后所形成的字符序列.令给定的字符序列X=“x ...
- 【BZOJ2423】[HAOI2010]最长公共子序列 DP
[BZOJ2423][HAOI2010]最长公共子序列 Description 字符序列的子序列是指从给定字符序列中随意地(不一定连续)去掉若干个字符(可能一个也不去掉)后所形成的字符序列.令给定的字 ...
随机推荐
- webpack--第三方loader
1.配置处理css样式表的第三方loader webpack默认只能打包处理js类型的文件,无法处理非js类型的文件:要想处理*.css文件,需要手动安装一下合适的第三方loader加载器: npm ...
- CF718C Sasha and Array 线段树 + 矩阵乘法
有两个操作: 将 $[l,r]$所有数 + $x$ 求 $\sum_{i=l}^{r}fib(i)$ $n=m=10^5$ 直接求不好求,改成矩阵乘法的形式: $a_{i}=M^x\times ...
- 2018百度之星初赛B轮 rect
rect Accepts: 1654 Submissions: 2948 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 131072/131 ...
- 【Leetcode】二分法
题目: 在排序数组中查找元素的第一个和最后一个位置. 二分法的思想非常简单,然而其中的实现细节非常繁琐,容易出错.本推文非常详细地介绍二分法的实现细节. 总结几点注意事项: 初始上.下界的取值: 判断 ...
- Ajax异步提交的步骤
1.创建XHR对象 ,XMLHttpRequest(该对象负责悄悄滴与服务器进行交互): 2.设置响应函数/回调函数(响应函数规定对返回自服务器的信息如何进行处理): 3.通过xmlhttp.open ...
- Python3学习笔记(六):字符串
一.基本字符串操作 所有标准的序列操作(索引.分片.乘法.判断成员资格.求长度.取最小值和最大值)对字符串同样适用.但是字符串是不可改变的. 二.字符串格式化 字符串格式化使用字符串格式化操作符(%) ...
- 南京网络赛 E K Sum
K Sum 终于过了这玩意啊啊啊==== 莫比乌斯反演,杜教筛,各种分块,积性函数怎么线性递推还很迷==,得继续研究研究 #include<bits/stdc++.h> using nam ...
- Failed to read artifact descriptor for xxx:jar
在MyEclipse中执行Maven的install命令时,报“Failed to read artifact descriptor for xxx:jar ”的错误.这可能是在下载过程中文件出现错误 ...
- php 的路由简介 (一个简单的路由模式)
<?php $_SERVER['REQUEST_URI'] = '/post/edit/1024?foo=bar'; $uri = explode('/', parse_url($_SERVER ...
- 关于Anaconda的虚拟环境操作
# 1.创建虚拟环境 conda create -n env_name python==版本号 # 2.激活虚拟环境 conda activate env_name # 3.下载相关模块 pip in ...