题目链接:戳我

30分暴力。。。。暴力提取子序列即可qwqwq

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<map>
#define MAXN 5010
using namespace std;
int lena,lenb,n,ans,cnt;
int dp[MAXN][MAXN];
char a[MAXN],b[MAXN],cur[MAXN],pre[MAXN];
map<string,int>sum;
inline void init(int pos)
{
if(cnt==n)
{
string s;
for(int i=1;i<=cnt;i++) s+=pre[i];
sum[s]++;
return;
}
if(pos>=lenb) return;
for(int i=pos+1;i<=lenb;i++)
{
pre[++cnt]=b[i];
init(i);
cnt--;
}
}
inline void solve(int pos)
{
if(cnt==n)
{
string s;
for(int i=1;i<=cnt;i++) s+=cur[i];
ans+=sum[s];
return;
}
if(pos>=lena) return;
for(int i=pos+1;i<=lena;i++)
{
cur[++cnt]=a[i];
solve(i);
cnt--;
}
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("ce.in","r",stdin);
freopen("ce.out","w",stdout);
#endif
scanf("%s%s",a+1,b+1);
lena=strlen(a+1)-1;
lenb=strlen(b+1)-1;
for(int i=1;i<=lena;i++)
{
for(int j=1;j<=lenb;j++)
{
dp[i][j]=max(dp[i-1][j],dp[i][j-1]);
if(a[i]==b[j]) dp[i][j]=max(dp[i][j],dp[i-1][j-1]+1);
}
}
n=dp[lena][lenb];
init(0);
cnt=0;
solve(0);
printf("%d\n%d\n",n,ans);
return 0;
}

考虑满分算法?题解的话强烈安利Flash_hu dalao的题解

第一问很好做,也就是f[i][j]表示第一个序列到第i位,第二个序列到第j位,最长的公共子序列的长度。f[i][j]可以从f[i-1][j]和f[i][j-1]转移过来,如果a[i]==b[j]的话还可以从f[i-1][j-1]+1转移过来。

对于第二问,我们设sum[i][j]表示第一个序列到第i位,第二个序列到第j位,最长公共子序列长度为f[i][j]的子序列个数。显然如果f[i-1][j]f[i][j]的话,我们是可以从sum[i-1][j]转移过来的,f[i][j-1]f[i][j]同理。额外的,如果f[i-1][j-1]+1==f[i][j]时,我们还可以累加sum[i-1][j-1]的答案。

就这样就结束了吗?不对,你会发现W掉了。为什么呢?

这是因为如果当f[i-1][j-1]==f[i][j]的时候,sum[i-1][j-1]的值对sum[i-1][j]和sum[i][j-1]各贡献了一次。而我们累加到sum[i][j]的时候相当于重算了一次,所以还要记得减去哦qwqwq

代码如下:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#define MAXN 5010
#define mod 100000000
using namespace std;
int lena,lenb;
int f[2][MAXN],sum[2][MAXN];
char a[MAXN],b[MAXN];
int main()
{
#ifndef ONLINE_JUDGE
freopen("ce.in","r",stdin);
freopen("ce.out","w",stdout);
#endif
scanf("%s%s",a+1,b+1);
lena=strlen(a+1)-1,lenb=strlen(b+1)-1;
for(int i=0;i<=lenb;i++) sum[0][i]=1;
sum[1][0]=1;
for(int i=1;i<=lena;i++)
{
for(int j=1;j<=lenb;j++)
{
sum[1][j]=0;
f[1][j]=max(f[1][j-1],f[0][j]);
if(a[i]==b[j]) f[1][j]=max(f[1][j],f[0][j-1]+1);
if(a[i]==b[j]&&f[0][j-1]+1==f[1][j]) sum[1][j]+=(sum[1][j]+sum[0][j-1])%mod;
if(f[1][j-1]==f[1][j]) sum[1][j]=(sum[1][j]+sum[1][j-1])%mod;
if(f[0][j]==f[1][j]) sum[1][j]=(sum[1][j]+sum[0][j])%mod;
if(a[i]!=b[j]&&f[0][j-1]==f[1][j]) sum[1][j]=(sum[1][j]+mod-sum[0][j-1])%mod;
}
swap(f[0],f[1]),swap(sum[0],sum[1]);
}
printf("%d\n%d\n",f[0][lenb],sum[0][lenb]);
return 0;
}

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

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

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

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

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

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

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

  4. bzoj:2423: [HAOI2010]最长公共子序列

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

  5. [HAOI2010]最长公共子序列(LCS+dp计数)

    字符序列的子序列是指从给定字符序列中随意地(不一定连续)去掉若干个字符(可能一个也不去掉)后所形成的字符序列.令给定的字符序列X=“x0,x1,…,xm-1”,序列Y=“y0,y1,…,yk-1”是X ...

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

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

  7. LG2516 【[HAOI2010]最长公共子序列】

    前言 感觉这几篇仅有的题解都没说清楚,并且有些还是错的,我再发一篇吧. 分析 首先lcs(最长公共子序列)肯定是板子.但这题要求我们不能光记lcs是怎么打的,因为没这部分分,并且另外一个方程的转移要用 ...

  8. 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])) ...

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

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

随机推荐

  1. Spring Boot tomcat参数

    主题 初学SpringBoot,想要配置一下tomcat的端口,以前tomcat直接在它的XML里配置就好了.现在SpringBoot直接继承了,不知道哪里配置.后来找到解决方法,记录一下. 具体方法 ...

  2. visjs使用小记-1.创建一个简单的网络拓扑图

    1.插件官网:http://visjs.org/ 2.创建一个简单的网络拓扑图 <!doctype html> <html> <head> <title> ...

  3. SPI子系统分析之四:驱动模块

    内核版本:3.9.5 SPI控制器层(平台相关) 上一节讲了SPI核心层的注册和匹配函数,它是平台无关的.正是在核心层抽象了SPI控制器层的相同部分然后提供了统一的API给SPI设备层来使用.我们这一 ...

  4. apktool.bat

    @echo off if "%PATH_BASE%" == "" set PATH_BASE=%PATH% set PATH=%CD%;%PATH_BASE%; ...

  5. UsePass & GrabPass

    [UsePass] The UsePass command uses named passes from another shader. [Syntax] UsePass "Shader/N ...

  6. 在SharePoint解决方案中使用JavaScript (2) – 模块化

    本文是在SharePoint中使用JavaScript的第二篇文章,前面的文章包括: 在SharePoint解决方案中使用JavaScript (0) 在SharePoint解决方案中使用JavaSc ...

  7. 【总结整理】AI产品经理大会2017(转载)

    从企业大数据到企业 AI | 易观智慧院院长 李智 1.AI 不是目的,而是要了解 AI 是什么,真正意义上的强人工智能在前沿领域尚未取得突破,暂时只能在影视文学作品中去思考人机关系.机器人三定律在未 ...

  8. Openssl genrsa命令

    一.简介 生成RSA私有密钥 二.语法 openssl genrsa [-out filename] [-passout arg] [-f4] [-] [-rand file(s)] [-engine ...

  9. Openssl s_server命令

    一.简介 s_server是openssl提供的一个SSL服务程序.使用此程序前,需要生成各种证书.本命令可以用来测试ssl客户端,比如各种浏览器的https协议支持 二.语法 openssl s_s ...

  10. cakephp中sql查询between

    $trading_list = $this->Trading->find('all', array('conditions' => array('buy_time BETWEEN ? ...