【BZOJ3864】Hero meet devil

Description

There is an old country and the king fell in love with a devil. The devil always asks the king to do some crazy things. Although the king used to be wise and beloved by his people. Now he is just like a boy in love and can’t refuse any request from the devil. Also, this devil is looking like a very cute Loli.
After the ring has been destroyed, the devil doesn't feel angry, and she is attracted by z*p's wisdom and handsomeness. So she wants to find z*p out.
But what she only knows is one part of z*p's DNA sequence S leaving on the broken ring.
Let us denote one man's DNA sequence as a string consist of letters from ACGT. The similarity of two string S and T is the maximum common subsequence of them, denote by LCS(S,T).
After some days, the devil finds that. The kingdom's people's DNA sequence is pairwise different, and each is of length m. And there are 4^m people in the kingdom.
Then the devil wants to know, for each 0 <= i <= |S|, how many people in this kingdom having DNA sequence T such that LCS(S,T) = i.
You only to tell her the result modulo 10^9+7.

Input

The first line contains an integer T, denoting the number of the test cases.
For each test case, the first line contains a string S. the second line contains an integer m.
T<=5
|S|<=15. m<= 1000.

Output

For each case, output the results for i=0,1,...,|S|, each on a single line.

Sample Input

1
GTC
10

Sample Output

1
22783
528340
497452

题意:给你一个串S,问所有长度为m的字符串中,与S串的最长公共子序列长度为1...|S|的串的个数。

题解:话说这种DP套DP的题最近有点流行~

还记得怎么求最长公共子序列吗?记得那个求最长公共子序列时的矩阵吗?不记得我就再说一遍。

令f[i][j]表示T串中到了第i个数,S串中到了第j个数,的LCS的长度。那么经典的DP方程:

$f[i][j]=max(f[i-1][j],f[i][j-1],(T[i]==S[j])?(f[i-1][j-1]+1):0)$

好了,但是我们求的是方案数,如果直接这样DP的话,需要记录的状态非常多(当前T可能的字符,之前T可能的字符。。。)。但是我们发现S的长度非常小,可以考虑把它单独拿出来处理一下。

因为每一行只能从上一行转移过来,我们不妨状压所有可能的行,暴力计算出在T中添加一个字符后会转移到哪个行。但是行中每一位的数不是0/1,差分一下就好了。处理出所有的转移后,再跑一个DP统计答案就行了。

#include <cstdio>
#include <cstring>
#include <iostream>
#include <cstring>
using namespace std;
const int mod=1000000007;
int n,m;
int to[1<<16][4],s[20],cnt[1<<16],f[2][1<<16],ans[20];
char str[20];
void init()
{
memset(to,0,sizeof(to));
memset(cnt,0,sizeof(cnt));
memset(f,0,sizeof(f));
memset(ans,0,sizeof(ans));
int i,j,k,s1,s2,t1,t2,tar;
for(i=0;i<(1<<n);i++)
{
if(i) cnt[i]=cnt[i-(i&-i)]+1;
for(j=0;j<4;j++)
{
for(tar=s1=s2=t1=t2=0,k=0;k<n;k++)
{
t1=s1,t2=s2,s2+=((i>>k)&1),s1=max(t1,s2);
if(s[k]==j) s1=max(s1,t2+1);
tar|=((s1-t1)<<k);
}
to[i][j]=tar;
}
}
}
void work()
{
scanf("%s%d",str,&m),n=strlen(str);
int i,j;
for(i=0;i<n;i++)
{
if(str[i]=='A') s[i]=0;
if(str[i]=='G') s[i]=1;
if(str[i]=='C') s[i]=2;
if(str[i]=='T') s[i]=3;
}
init();
f[0][0]=1;
for(j=0;j<=m;j++)
{
for(i=0;i<(1<<n);i++) f[(j&1)^1][i]=0;
for(i=0;i<(1<<n);i++) f[(j&1^1)][to[i][0]]=(f[j&1^1][to[i][0]]+f[j&1][i])%mod,f[(j&1^1)][to[i][1]]=(f[j&1^1][to[i][1]]+f[j&1][i])%mod,f[(j&1^1)][to[i][2]]=(f[j&1^1][to[i][2]]+f[j&1][i])%mod,f[(j&1^1)][to[i][3]]=(f[j&1^1][to[i][3]]+f[j&1][i])%mod;
}
for(i=0;i<(1<<n);i++) ans[cnt[i]]=(ans[cnt[i]]+f[m&1][i])%mod;
for(i=0;i<=n;i++) printf("%d\n",ans[i]);
}
int main()
{
int T;
scanf("%d",&T);
while(T--) work();
return 0;
}

【BZOJ3864】Hero meet devil DP套DP的更多相关文章

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

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

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

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

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

  4. HDU 4899 Hero meet devil (状压DP, DP预处理)

    题意:给你一个基因序列s(只有A,T,C,G四个字符,假设长度为n),问长度为m的基因序列s1中与给定的基因序列LCS是0,1......n的有多少个? 思路:最直接的方法是暴力枚举长度为m的串,然后 ...

  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

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

  7. DP套DP

    DP套DP,就是将内层DP的结果作为外层DP的状态进行DP的方法. [BZOJ3864]Hero meet devil 对做LCS的DP数组差分后状压,预处理出转移数组,然后直接转移即可. tr[S] ...

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

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

  9. [模板] dp套dp && bzoj5336: [TJOI2018]party

    Description Problem 5336. -- [TJOI2018]party Solution 神奇的dp套dp... 考虑lcs的转移方程: \[ lcs[i][j]=\begin{ca ...

随机推荐

  1. 大话Spark(4)-一文理解MapReduce Shuffle和Spark Shuffle

    Shuffle本意是 混洗, 洗牌的意思, 在MapReduce过程中需要各节点上同一类数据汇集到某一节点进行计算,把这些分布在不同节点的数据按照一定的规则聚集到一起的过程成为Shuffle. 在Ha ...

  2. python在程序中通过Windows打开文件

    import os os.startfile(r'D:\test_input.html')

  3. Jenkins+ProGet+Windows Batch搭建全自动的内部包(NuGet)打包和推送及管理平台

    这一篇文章是继http://www.cnblogs.com/EasonJim/p/5954155.html的升级版,由于CCNET已经过时,所以我把打包过程的CCNET工具换成Jenkins去实现,批 ...

  4. php cli模式下调试

    //设置内存大小 ini_set('memory_limit','512M'); //打开日志 ini_set('log_errors', 'On'); //定向日志记录文件 ini_set('err ...

  5. oracle如何获得新插入记录的id

    .对于提交(最后一次操作commit了)的话可以查询那个提交段 SELECT 列名1,列名2…… FROM 表名 VERSIONS BETWEEN TIMESTAMP MINVALUE AND MAX ...

  6. {}在javascript与(python,java)中的含义区别

    {}在javascript中是对象,其访问属性的方法为 a.name,a['name'],参见http://www.itxueyuan.org/view/6332.html {}在python,jav ...

  7. 【Python】使用类和实例

    Car类 class Car(): '''模拟汽车''' def __init__(self,name,model,year): '''初始化汽车的属性''' self.name = name sel ...

  8. 微信小程序实战 购物车功能

    代码地址如下:http://www.demodashi.com/demo/12400.html 一.准备工作 软件环境:微信开发者工具 官方下载地址:https://mp.weixin.qq.com/ ...

  9. js 解析json字符串

    server端返回的数据例如以下: {"list":[{"id":1,"name":"汉族"},{"id&qu ...

  10. HDU 5042 GCD pair 预处理+二分 分段

    点击打开链接 #include <stdio.h> #include <string.h> #include <iostream> #include <cma ...