题目传送门

题目大意

给出一个长度为 \(n\) 的字符串,对于每个 \(k\in [0,n]\),求出有多少个长度为 \(m\) 的字符串满足两者最长公共子序列长度为 \(k\)。

\(n\le 15,m\le 10^3\),答案对 \(10^9+7\) 取模。

思路

难得扣shi。。。

首先,我们发现如果对两个已知字符串求最长公共子序列,那么我们可以设 \(f_{i,j}\) 表示第 1 个字符串匹配到 \(i\),第 2 个字符串匹配到 \(j\) 的最长匹配长度。不难得到转移式:

\[f_{i,j}=f_{i-1,j-1}+1\{a_i=b_j\}
\]
\[f_{i,j}=\max\{f_{i-1,j},f_{i,j-1}\}
\]

于是你发现我们一个字符串其实并不需要知道每一位,我们只需要知道 \(f_{i,j}\) 即可。但是你发现你不好把这个压进状态里面,但是你发现对于每一个 \(i\),\(j\) 每变化 \(1\) 位答案最多只会增加 \(1\),于是你可以考虑把每一位的增加量存进状态里面,这样你就可以做到 \(\Theta(2^nm)\)了。

\(\texttt{Code}\)

#include <bits/stdc++.h>
using namespace std; #define Int register int
#define mod 1000000007
#define MAXM 1005
#define MAXN 15 template <typename T> inline void read (T &t){t = 0;char c = getchar();int f = 1;while (c < '0' || c > '9'){if (c == '-') f = -f;c = getchar();}while (c >= '0' && c <= '9'){t = (t << 3) + (t << 1) + c - '0';c = getchar();} t *= f;}
template <typename T,typename ... Args> inline void read (T &t,Args&... args){read (t);read (args...);}
template <typename T> inline void write (T x){if (x < 0){x = -x;putchar ('-');}if (x > 9) write (x / 10);putchar (x % 10 + '0');} char s[MAXN];
int n,m,ans[MAXN],dp[1 << MAXN][MAXM];
void Add (int &a,int b){a = a + b >= mod ? a + b - mod : a + b;} int a[MAXN],b[MAXN],trans[1 << MAXN][4]; int getid (char c){return c == 'A' ? 0 : (c == 'T' ? 1 : (c == 'C' ? 2 : 3));} void init (){
for (Int S = 0;S < 1 << n;++ S){
for (Int i = 1;i <= n;++ i) a[i] = a[i - 1] + (S >> i - 1 & 1);
for (Int i = 0;i < 4;++ i){
for (Int j = 1;j <= n;++ j)
if (getid (s[j]) == i) b[j] = a[j - 1] + 1;
else b[j] = max (b[j - 1],a[j]);
trans[S][i] = 0;
for (Int j = 1;j <= n;++ j) trans[S][i] |= b[j] - b[j - 1] << j - 1;
}
}
} int popcount (int S){
int res = 0;for (Int i = 0;i < n;++ i) res += S >> i & 1;
return res;
} signed main(){
int t;read (t);
while (t --> 0){
scanf ("%s",s + 1),read (m);
n = strlen (s + 1),init ();
memset (dp,0,sizeof (dp)),dp[0][0] = 1;
for (Int i = 0;i < m;++ i)
for (Int S = 0;S < 1 << n;++ S)
for (Int j = 0;j < 4;++ j)
Add (dp[trans[S][j]][i + 1],dp[S][i]);
for (Int i = 0;i <= n;++ i) ans[i] = 0;
for (Int S = 0;S < 1 << n;++ S) Add (ans[popcount (S)],dp[S][m]);
for (Int i = 0;i <= n;++ i) write (ans[i]),putchar ('\n');
}
return 0;
}

题解 Hero meet devil的更多相关文章

  1. 【BZOJ3864】Hero meet devil DP套DP

    [BZOJ3864]Hero meet devil Description There is an old country and the king fell in love with a devil ...

  2. bzoj 3864: Hero meet devil [dp套dp]

    3864: Hero meet devil 题意: 给你一个只由AGCT组成的字符串S (|S| ≤ 15),对于每个0 ≤ .. ≤ |S|,问 有多少个只由AGCT组成的长度为m(1 ≤ m ≤ ...

  3. BZOJ 3864 Hero meet devil 超详细超好懂题解

    题目链接 BZOJ 3864 题意简述 设字符集为ATCG,给出一个长为\(n(n \le 15)\)的字符串\(A\),问有多少长度为\(m(m \le 1000)\)的字符串\(B\)与\(A\) ...

  4. BZOJ3864 & HDU4899:Hero meet devil——题解

    https://www.lydsy.com/JudgeOnline/problem.php?id=3864 http://acm.hdu.edu.cn/showproblem.php?pid=4899 ...

  5. bzoj3864: Hero meet devil

    Description There is an old country and the king fell in love with a devil. The devil always asks th ...

  6. HDU 4899 Hero meet devil(状压DP)(2014 Multi-University Training Contest 4)

    Problem Description There is an old country and the king fell in love with a devil. The devil always ...

  7. BZOJ3864: Hero meet devil(dp套dp)

    Time Limit: 8 Sec  Memory Limit: 128 MBSubmit: 397  Solved: 206[Submit][Status][Discuss] Description ...

  8. BZOJ3864: Hero meet devil【dp of dp】

    Description There is an old country and the king fell in love with a devil. The devil always asks th ...

  9. bzoj 3864: Hero meet devil(dp套dp)

    题面 给你一个只由\(AGCT\)组成的字符串\(S (|S| ≤ 15)\),对于每个\(0 ≤ .. ≤ |S|\),问 有多少个只由\(AGCT\)组成的长度为\(m(1 ≤ m ≤ 1000) ...

随机推荐

  1. 跨平台APP推荐收藏

    时间:2019-04-11 整理:pangYuaner 标题:十大跨平台优秀软件 地址:https://www.cnblogs.com/the-king-of-cnblogs/p/3154758.ht ...

  2. Red Hat Enterprise Linux 7.2修改主机名(hostname)

    Red Hat Enterprise Linux 7.2在安装的时候,会默认生成主机名:localhost. 那么如何修改成自己想要的自己名? //格式为:用户名@主机名 比如: [root@loca ...

  3. 「山东省队集训2021 Round 1」 半夜

    考虑将 \(X\) 复制一次放到后面再对其长度为 \(n\) 的连续子串和 \(Y\) 求一波 \(\rm{Longest\ Common\ Subsequence}\) 就能得到 \(\Theta( ...

  4. Robot Framework 面试题

    什么是 RF 基于可扩展关键字驱动的自动化测试框架 什么是可扩展关键字驱动 可扩展意味着可以自己开发,也可以调用第三方的关键字库 关键字驱动意味着测试用例都是围绕着关键字运行的 RF 的原理(框架?) ...

  5. Mysql常用sql语句(6)- limit 限制查询结果的条数

    测试必备的Mysql常用sql语句系列 https://www.cnblogs.com/poloyy/category/1683347.html 前言 实际工作中,我们的数据表数据肯定都是万级别的,如 ...

  6. Filter案例之敏感词过滤和代理模式

    一.需求分析 二 .代理模式 1.概念 2.代码实现 代理对象可以强转为真实对象,即对应的接口类: 3.通过代理增强方法 其中,方法对象invoke真实对象,反射原理: 三.过滤敏感词汇案例代码实现 ...

  7. linux下制作img文件

    一.简介 制作img文件可以使用linux系统中的dd命令制作,Linux dd 命令用于读取.转换并输出数据.dd 可从标准输入或文件中读取数据,根据指定的格式来转换数据,再输出到文件.设备或标准输 ...

  8. vue中如何深度监听一个对象?

    大家都知道,Vue项目中对数据的监听,提供了一个很好的钩子watch,watch可以极其方便的监听我们常用数据类型值的变化,但通常当我们想监听一个对象中,某个属性值的变化时,很难达到我们预期的效果.那 ...

  9. JavaScript中的async/await详解

    1.前言 ​ async函数,也就是我们常说的async/await,是在ES2017(ES8)引入的新特性,主要目的是为了简化使用基于Promise的API时所需的语法.async和await关键字 ...

  10. Docker安装flink及避坑指南

    Docker安装flink 导航 无处不在的大数据 安装flink 拉取flink镜像 编写docker-compose.yml 生成启动 查看安装效果 常见坑及解决方案 问题1 问题2 参考   本 ...