LG2516 【[HAOI2010]最长公共子序列】
前言
感觉这几篇仅有的题解都没说清楚,并且有些还是错的,我再发一篇吧。
分析
首先lcs(最长公共子序列)肯定是板子。但这题要求我们不能光记lcs是怎么打的,因为没这部分分,并且另外一个方程的转移要用到状态的定义。在此定义状态:
设题设字符串为\(S\),\(T\),然后定义字符串的前缀\(i\)表示字符串开头至\(i\)位置构成的字符串,例如\(S\)的前缀\(i\)表示\(S_1\sim S_i\)。
\(f(i,j)\)表示\(S\)的前缀\(i\)和\(T\)的前缀\(j\)的lcs的长度,根据广为人知的lcs算法,
\]
前两个转移式子表示不匹配\(S_i\)和\(T_j\),最后的式子表示\(S_i\)和\(T_j\)匹配并将其贡献计入答案。
考虑新状态\(g(i,j)\)表示同上解释的lcs的匹配方式对数。那么如何转移呢?首先若\(f(i,j)\)等于不匹配转移式子,那么就不匹配转移式子对应的\(g\)应计入答案,因为若\(f\)不改变,那么匹配方式及其对数也应不变。然后考虑两种特殊情况:
- \[f(i,j)=f(i-1,j-1)\&S_i\neq T_j$$它描述的是$S_i$和$T_j$都不做出贡献而直接转移重复的情况,那么根据容斥原理,就应减去$g(i-1,j-1)$。
\]
复杂度
时间是\(O(n\cdot m)\)的,没问题。但是朴素代码空间复杂度也是\(O(n\cdot m)\)的,128MB要炸空间,于是要用滚动数组。
代码
借鉴kiddingme12138的,他的代码(以及很多人的)虽然能AC但是有错,即特殊情况2中无论\(f(i,j)\)最终是否等于\(f(i-1,j-1)+1\)只要\(S_i=T_j\)那么就加上\(g(i-1,j-1)\)。望加强数据。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<map>
#define rg register
using namespace std;
const int MAXN=5e3+7;
const int mod=1e8;
int n,m;
char S[MAXN],T[MAXN];
int f[2][MAXN],g[2][MAXN];
int main()
{
// freopen("lcs.in","r",stdin);
// freopen("lcs.out","w",stdout);
scanf("%s",S+1);
n=strlen(S+1)-1;
scanf("%s",T+1);
m=strlen(T+1)-1;
int cur=0;
for(rg int i=0;i<=m;++i)
g[cur][i]=1;
for(rg int i=0;i<=n;++i)
{
cur^=1;g[cur][0]=1;
for(rg int j=1;j<=m;++j)
{
g[cur][j]=0;
f[cur][j]=max(f[cur^1][j],f[cur][j-1]);
if(S[i]==T[j])
f[cur][j]=max(f[cur][j],f[cur^1][j-1]+1);
if(f[cur][j]==f[cur^1][j])
g[cur][j]+=g[cur^1][j];
if(f[cur][j]==f[cur][j-1])
g[cur][j]+=g[cur][j-1];
if(S[i]==T[j]&&f[cur][j]==f[cur^1][j-1]+1)
g[cur][j]+=g[cur^1][j-1];
if(S[i]!=T[j]&&f[cur][j]==f[cur^1][j-1])
g[cur][j]-=g[cur^1][j-1];
g[cur][j]=(g[cur][j]+mod)%mod;
}
}
printf("%d\n%d",f[cur][m],g[cur][m]);
}
LG2516 【[HAOI2010]最长公共子序列】的更多相关文章
- [BZOJ2423][HAOI2010]最长公共子序列
[BZOJ2423][HAOI2010]最长公共子序列 试题描述 字符序列的子序列是指从给定字符序列中随意地(不一定连续)去掉若干个字符(可能一个也不去掉)后所形成的字符序列.令给定的字符序列X=“x ...
- 【BZOJ2423】[HAOI2010]最长公共子序列 DP
[BZOJ2423][HAOI2010]最长公共子序列 Description 字符序列的子序列是指从给定字符序列中随意地(不一定连续)去掉若干个字符(可能一个也不去掉)后所形成的字符序列.令给定的字 ...
- 2021.12.10 P2516 [HAOI2010]最长公共子序列(动态规划+滚动数组)
2021.12.10 P2516 [HAOI2010]最长公共子序列(动态规划+滚动数组) https://www.luogu.com.cn/problem/P2516 题意: 给定字符串 \(S\) ...
- bzoj:2423: [HAOI2010]最长公共子序列
Description 字符序列的子序列是指从给定字符序列中随意地(不一定连续)去掉若干个字符(可能一个也不去掉)后所形成的字符序列.令给定的字符序列X=“x0,x1,…,xm-1”,序列Y=“y0, ...
- [HAOI2010]最长公共子序列(LCS+dp计数)
字符序列的子序列是指从给定字符序列中随意地(不一定连续)去掉若干个字符(可能一个也不去掉)后所形成的字符序列.令给定的字符序列X=“x0,x1,…,xm-1”,序列Y=“y0,y1,…,yk-1”是X ...
- 洛谷P2516 [HAOI2010]最长公共子序列(LCS,最短路)
洛谷题目传送门 一进来就看到一个多月前秒了此题的ysn和YCB%%% 最长公共子序列的\(O(n^2)\)的求解,Dalao们想必都很熟悉了吧!不过蒟蒻突然发现,用网格图貌似可以很轻松地理解这个东东? ...
- HAOI2010 最长公共子序列
题目链接:戳我 30分暴力....暴力提取子序列即可qwqwq #include<iostream> #include<cstdio> #include<algorith ...
- 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])) ...
- 洛谷 P2516 [HAOI2010]最长公共子序列
题目传送门 解题思路: 第一问要求最长公共子序列,直接套模板就好了. 第二问要求数量,ans[i][j]表示第一个字符串前i个字符,第二个字符串前j个字符的最长公共子序列的数量 如果f[i][j]是由 ...
随机推荐
- 老毛桃制作装机版u盘
启动盘准备工作: ① 老毛桃官网首页下载老毛桃v9.3装机版u盘启动盘制作工具安装到电脑上: ② 准备一个容量大在4G以上并能够正常使用的u盘. 第一步 到老毛桃官网中下载老毛桃v9.3安装包到系统桌 ...
- 用c++写一个数据库
[cpp] view plain copy 第一步:构建一个头文件(**.h) [cpp] view plain copy #include<iostream> #include<i ...
- Linux学习 : 总线-设备-驱动模型
platform总线是一种虚拟的总线,相应的设备则为platform_device,而驱动则为platform_driver.Linux 2.6的设备驱动模型中,把I2C.RTC.LCD等都归纳为pl ...
- SQL-24 获取所有非manager员工当前的薪水情况,给出dept_no、emp_no以及salary ,当前表示to_date='9999-01-01'
题目描述 获取所有非manager员工当前的薪水情况,给出dept_no.emp_no以及salary ,当前表示to_date='9999-01-01'CREATE TABLE `dept_emp` ...
- 循环神经网络-Dropout
dropout 是 regularization 方法,在rnn中使用方法不同于cnn 对于rnn的部分不进行dropout,也就是说从t-1时候的状态传递到t时刻进行计算时,这个中间不进行memor ...
- python 列表和元组
一,基本的列表操作 1.该表列表,元素赋值 示例: >>>x = [1,1,1] >>>x[1] = 2 >>>x [1,2,1] 2.删除元素 ...
- day 34 进程线程排序 抢票 初级生产者消费者
# 实现的内容 模拟购票 20个人买,就有一张购票查,的时候大家都看到,但是购买只能一人购买成功#利用互斥锁# from multiprocessing import Process,Lock# im ...
- 使用generator生成dao、mapping和model
我们在ssm框架开发的时候(不限于此框架),为了开发效率.有时候不得不提高一下代码速度.千篇一律的事情谁都头疼,比如写dao,写model,写mapping等等.不仅慢,而且一不留神,还会出错. 今天 ...
- 《统计学习方法》笔记(9):EM算法和隐马尔科夫模型
EM也称期望极大算法(Expectation Maximization),是一种用来对含有隐含变量的概率模型进行极大似然估计的迭代算法.该算法可应用于隐马尔科夫模型的参数估计. 1.含有隐含参数的概率 ...
- vue国际化插件
1.安装 $ npm install vue-i18n 2.引入 import VueI18n from 'vue-i18n' Vue.use(VueI18n) const i18n = new Vu ...