题目大意

给定一个由AGCT组成的串\(t\), 求对于所有的\(L \in [1, |t|]\), 有多少个由AGCT组成的串\(s\)满足\(LCS(s, t) = L\).

Solution

传说中的DP套DP.

我们用\(f_{i, j}\)表示\(s\)的前\(i\)位与\(t\)的前\(j\)位的最长公共子序列, 则我们有

\[f_{i, j} = \max \begin{cases} f_{i - 1, j} \\ f_{i, j - 1} \\ f_{i - 1, j - 1} + [s_i = t_j] \end{cases}
\]

则\(LCS(s, t) = f[|S|][|T|]\).

逐位考虑\(s\), 假设当前到\(s\)的第\(i\)位, 我们用\(F\)表示状态: \(F = \{ f[i][1], f[i][2], \cdots, f[i][|t|] \}\). 考虑当\(i\)变成\(i + 1\)时, \(F\)会怎么变化: 对于确定的\(t\), \(F\)的变化只与\(s[i + 1]\)有关, 因此我们令\(c =s[i + 1]\), 用\(T(F, c)\)表示当\(s[i + 1] = c\)时\(F\)会变成怎么样.

我们用\(g[i][F]\)表示\(s\)的前\(i\)位与\(t\)的最长公共子序列状态为\(F\)的串\(s\)的数量, 则对于每一个\(c\), 有\(g[i + 1][T(F, c)] += g[i][F]\).

我们发现\(F\)不容易被记录, 又因为注意到\(0 \le F[i] - F[i - 1] \le 1\)且\(F[0] = 0\), 因此我们用\(S\)来表示\(\{ F[i] - F[i - 1] \}\)的状态集合. 这样我们就可以轻易地进行状态压缩了.

考虑怎么统计答案:

\[ans[k] = \sum_{F} g[|T|][F] \times [F[|T|] = k]
\]

#include <cstdio>
#include <cstring>
#include <algorithm> using namespace std;
const int N = 15, MOD = (int)1e9 + 7;
int t[N + 7];
int n, m;
int main()
{ #ifndef ONLINE_JUDGE freopen("gene.in", "r", stdin);
freopen("gene.out", "w", stdout); #endif int T; scanf("%d\n", &T);
for (int cs = 0; cs < T; ++ cs)
{
static char str[N + 7]; scanf("%s", str + 1);
n = strlen(str + 1); scanf("%d\n", &m);
for (int i = 1; i <= n; ++ i)
if (str[i] == 'A') t[i] = 1;
else if (str[i] == 'T') t[i] = 2;
else if (str[i] == 'G') t[i] = 3;
else if (str[i] == 'C') t[i] = 4;
static int trans[(1 << N) + 7][7];
for (int j = 0; j < 1 << n; ++ j) for (int c = 1; c <= 4; ++ c)
{
static int a[N + 7], b[N + 7];
memset(a, 0, sizeof a);
for (int k = 0; k < n; ++ k) a[k + 1] = a[k] + (j >> k & 1);
b[0] = 0;
for (int k = 1; k <= n; ++ k) b[k] = max(max(a[k], b[k - 1]), a[k - 1] + (c == t[k]));
int stt = 0;
for (int k = 0; k < n; ++ k) if (b[k + 1] - b[k]) stt |= 1 << k;
trans[j][c] = stt;
}
static int f[(1 << N) + 7], g[(1 << N) + 7];
memset(f, 0, sizeof f); f[0] = 1;
for (int i = 0; i < m; ++ i)
{
memset(g, 0, sizeof g);
for (int j = 0; j < 1 << n; ++ j) if (f[j]) for (int c = 1; c <= 4; ++ c)
g[trans[j][c]] = (g[trans[j][c]] + f[j]) % MOD;
swap(f, g);
}
static int ans[N + 7];
memset(ans, 0, sizeof ans);
for (int i = 0; i < 1 << n; ++ i)
{
int cnt = 0;
for (int tmp = i; tmp; tmp >>= 1) if (tmp & 1) ++ cnt;
ans[cnt] = (ans[cnt] + f[i]) % MOD;
}
for (int i = 0; i <= n; ++ i) printf("%d\n", ans[i]);
}
}

BZOJ 3864 Hero Meets Devil的更多相关文章

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

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

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

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

  3. bzoj 3864: Hero meet devil

    bzoj3864次元联通们 第一次写dp of dp (:з」∠) 不能再颓废啦 考虑最长匹配序列匹配书转移 由于dp[i][j]的转移可由上一行dp[i-1][j-1],dp[i-1][j],dp[ ...

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

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

  5. BZOJ 3864 Hero meet devil (状压DP)

    最近写状压写的有点多,什么LIS,LCSLIS,LCSLIS,LCS全都用状压写了-这道题就是一道状压LCSLCSLCS 题意 给出一个长度为n(n<=15)n(n<=15)n(n< ...

  6. 【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 ...

  7. bzoj千题计划241:bzoj3864: Hero meet devil

    http://www.lydsy.com/JudgeOnline/problem.php?id=3864 题意: 给你一个DNA序列,求有多少个长度为m的DNA序列和给定序列的LCS为0,1,2... ...

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

  9. bzoj3864: Hero meet devil

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

随机推荐

  1. hnust 最小的x

    问题 G: 最小的x 时间限制: 1 Sec  内存限制: 128 MB提交: 2347  解决: 1155[提交][状态][讨论版] 题目描述 TSQ对DK进行地狱式训练,找出满足下面公式的最小的x ...

  2. CentOS下创建和root权限完全相同用户

    新建用户 [root@bagon ~]# useradd newroot 修改密码 [root@bagon ~]# passwd newroot 编辑/etc/passwd,找到新建用户那一行 new ...

  3. Windows 下开发.NET Core应用

    一.使用Visual Studio 2015开发1.1 依次安装Visual Studio 2015 Update 3.NET Core 1.0.0 - VS 2015 Tooling Preview ...

  4. HashMap 的深入学习

    Java为数据结构中的映射定义了一个接口java.util.Map,此接口主要有四个常用的实现类,分别是HashMap.Hashtable.LinkedHashMap和TreeMap,类继承关系如下图 ...

  5. c语言为什么效率高

    文章:为什么和其他语言相比C语言是快速的语言 文章:C语言的应用领域有哪些? 虽然文章写的很差劲,但是仍然可以学到点知识. 计算机组成原理→DOS命令→汇编语言→C语言(不包括C++).代码书写规范→ ...

  6. MYSQL 简单的建库操作代码

    一.查询所有数据库 代码:show databases; 成功后如下图: 二.建立一个数据库 代码:create database test3: 成功后如下图: 三.连接数据库 代码:use test ...

  7. Custom LDAP Monitor Does Not Work

    Custom LDAP Monitor Does Not Work https://www.poppelgaard.com/netscaler-case-study-custom-ldap-monit ...

  8. 开头什么的肯定要自我介绍然后把它扔到置顶咯>_<~

    大家嚎,我是NanoApe~ 现在高一,是个OIer.音游狗和一个爱着二次元的萌汉子妹子,欢迎前来勾搭>_<~ 最近就是要冲省队啦~~~~加油! 扣扣号:879006461 Weibo:伪 ...

  9. 在有道词典程序文件夹发现一个后缀名为sql的数据库(SQLite)

    缘起 在清理电脑磁盘的时候,看一看各安装文件夹有占用了多大容量,发现有道词典居然达140MB了,于是进去看看. 发现个有趣的文件:XXX.sql. 首先我们看一看它的安装文件夹的结构: Dict └─ ...

  10. CSS 清除浮动的4种方法

    此为未清除浮动源代码,运行代码无法查看到父级元素浅黄色背景.<style type=”text/css”> <!– *{margin:0;padding:0;} body{font: ...