题目链接:戳我

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. nginx启动、重启、重新加载配置文件和平滑升级

    Nginx有一个主进程和几个工作进程,主进程的主要作用就是读取.评估配置文件和管理工作进程,工作进程对请求做实际处理.工作进程的数量是在配置文件中配置的,一般设置为cpu的核心数*线程数. nginx ...

  2. Python实现阿里云短信推送

    本篇文章是使用Python的Web框架Django提供发送短信接口供前端调用,Python版本2.7 阿里云入驻.申请短信服务.创建应用和模板等步骤请参考:阿里云短信服务入门 1.下载sdk 阿里云短 ...

  3. 反射与dynamic

    反射 var a = Assembly.GetExecutingAssembly(); Type type = a.GetType("CLRTest.ReflectClass"); ...

  4. UGUI防止穿透和判断点击的是否是UI

    用UGUI做的UI,比如按钮,点击一下,后面的3D物体也会接收到点击事件! 1.UGUI自带的防穿透代码: if (EventSystem.current.IsPointerOverGameObjec ...

  5. 快速上手Runtime(三)之方法交换

    开发过程中,我们经常会用到系统类,而它提供的方法又不能完全满足我们开发的需要,那么在此时,我们需要为系统自带的方法扩展一些功能,而且还要保证原有的功能可正常使用.假设咱们现在有这么一个需求,我们在调用 ...

  6. Scrapy Test

    (flappbird) luo@luo-ThinkPad-W540:~$ scrapy startproject myspider0315New Scrapy project 'myspider031 ...

  7. iOS端一次视频全屏需求的实现(转)

    对于一个带有视频播放功能的app产品来说,视频全屏是一个基本且重要的需求.虽然这个需求看起来很简单,但是在实现上,我们前后迭代了三套技术方案.这篇文章将介绍这三种实现方案中的利弊和坑点,以及实现过程中 ...

  8. linux系统的命令组与函数

    一.命令组 许多时候,我们在shell操作上,需要在一定条件下一次执行多个命令,也就是说,要么不执行,要么就全执行,而不是每次依序的判断是否要执行下一个命令.或是,需要从一些命令执行优先次顺中得到豁免 ...

  9. PythonScripter2.7报错ascii codec can't encode characters in position 0-1:ordinal not in range(128)

    1. 这是Python 2 mimetypes的bug2. 需要将Python2.7\lib\mimetypes.py文件中如下片段注释或删除:try: ctype = ctype.encode(de ...

  10. LINK : fatal error LNK1104: cannot open file "mfc42d.lib"

    VC++6.0上建立了个基于MFC应用程序,在编译时候没出现错误,但在LINK的是时候出现这样的错误:Linking...LINK : fatal error LNK1104: cannot open ...