bzoj3864-hdu4899-Hero meet devil
题目
给出一个由AGTC组成的字符串\(S\),长度为\(n\),对于每个\(i\in [0,n]\),问有多少个长度为\(m\),仅含有AGTC的字符串\(T\)使得\(S\)与\(T\)的最长公共子串长度为\(i\)。\((n\le 15,m\le 1000)\)
Sample Input
GTC
10
Sample Output
1
22783
528340
497452
分析
这是一个经典的问题,解法称为dp套dp。这一类问题要求解的是有多少种输入可以使得一个dp的最终结果为一个特定值。在这道题中的表现就是,求有多少个字符串\(T\)使得求解lcs的dp的最终结果为\(i\)。对于这类问题,一般的方法是,对于内部dp(这里的lcs)观察它的求解过程,把dp的过程状态压缩,放在外层dp中。
观察lcs的求解过程:
\begin{cases}
lcs[i-1][j-1]+1 & \text{if t[i]=s[j]} \\
lcs[i-1][j] \\
lcs[i][j-1]
\end{cases}
\]
注意到这个转移的过程中,一行只和上一行有关,而且同一行中相邻两位最多差1,所以我们可以把一行差分,状态压缩。即令\(f[i][j]\)表示枚举到第\(i\)个字符,这时候内层dp状态为\(j\)的情况数。那么可以直接得到计算方程:
f[i][trans(j,k)]+=f[i-1][j]
\end{aligned}
\]
其中\(trans(j,k)\)表示从\(j\)状态加一个字母\(k\)转移到的状态。比如说,\(s=\text{'ACT'},j=010\),由于差分过,所以原来的状态是\(011\),即当前的匹配是C。接下来加入一个T,那么状态会变成\(012\),压缩后变为\(011\)。注意到这个trans是固定的,所以可以每次预处理。
预处理复杂度为\(O(kn2^n)\),外层dp复杂度为\(O(km2^n)\)。
代码
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long giant;
const int maxn=15;
const int maxm=1<<maxn;
const int maxa=1e3+1;
const int q=1e9+7;
const char sta[]=" ACGT";
char s[maxn+1];
int t[maxm][5],f[maxa+2][maxm+2],ans[maxn+2],n,a[maxn+2];
int change(char c) {
for (int i=1;i<=4;++i) if (c==sta[i]) return i;
return 5;
}
void add(int &x,int y) {
x+=y;
if (x>q) x-=q;
}
int count(int x) {
int ret=0;
for (int i=0;i<maxn;++i) ret+=((x>>i)&1);
return ret;
}
int tf[2][maxn+2];
int trans(int sit,int c) {
memset(tf,0,sizeof tf);
for (int i=0;i<n;++i) tf[0][i+1]=tf[0][i]+((sit>>i)&1);
for (int i=1;i<=n;++i) {
int tmp=0;
if (a[i]==c) tmp=max(tmp,tf[0][i-1]+1);
tmp=max(tmp,max(tf[0][i],tf[1][i-1]));
tf[1][i]=tmp;
}
int ret=0;
for (int i=0;i<n;++i) ret+=(1<<i)*(tf[1][i+1]-tf[1][i]);
return ret;
}
int main() {
#ifndef ONLINE_JUDGE
freopen("test.in","r",stdin);
freopen("my.out","w",stdout);
#endif
int T;
scanf("%d",&T);
while (T--) {
memset(ans,0,sizeof ans);
memset(f,0,sizeof f);
memset(a,0,sizeof a);
scanf("%s",s+1);
n=strlen(s+1);
int m;
scanf("%d",&m);
f[0][0]=1;
for (int i=1;i<=n;++i) a[i]=change(s[i]);
for (int j=0;j<(1<<n);++j) for (int k=1;k<=4;++k) t[j][k]=trans(j,k);
for (int i=1;i<=m;++i) {
for (int j=0;j<(1<<n);++j) {
for (int k=1;k<=4;++k) {
int s=t[j][k];
add(f[i][s],f[i-1][j]);
}
}
}
for (int i=0;i<(1<<n);++i) add(ans[count(i)],f[m][i]);
for (int i=0;i<=n;++i) printf("%d\n",ans[i]);
}
return 0;
}
bzoj3864-hdu4899-Hero meet devil的更多相关文章
- 【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 ...
- HDU4899 Hero meet devil DP套DP
陈老师的题QwQ 原题链接 题目大意 有两个字符串\(S\)和\(T\)(都只能由'A','C','G','T'这四个字符组成),\(S\)已知\(T\)未知,还知道\(S\)的长度为\(m\).求满 ...
- hdu4899 Hero meet devil
题目链接 题意 给出一个长度字符串\(T\),其中只包含四种字符\((A,C,G,T)\),需要找一个字符串\(S\),使得\(S\)的长度为\(m\),问\(S\)和\(T\)的\(lcs\)为\( ...
- bzoj 3864: Hero meet devil [dp套dp]
3864: Hero meet devil 题意: 给你一个只由AGCT组成的字符串S (|S| ≤ 15),对于每个0 ≤ .. ≤ |S|,问 有多少个只由AGCT组成的长度为m(1 ≤ m ≤ ...
- BZOJ3864 & HDU4899:Hero meet devil——题解
https://www.lydsy.com/JudgeOnline/problem.php?id=3864 http://acm.hdu.edu.cn/showproblem.php?pid=4899 ...
- bzoj3864: Hero meet devil
Description There is an old country and the king fell in love with a devil. The devil always asks th ...
- BZOJ3864: Hero meet devil(dp套dp)
Time Limit: 8 Sec Memory Limit: 128 MBSubmit: 397 Solved: 206[Submit][Status][Discuss] Description ...
- 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 ...
- bzoj千题计划241:bzoj3864: Hero meet devil
http://www.lydsy.com/JudgeOnline/problem.php?id=3864 题意: 给你一个DNA序列,求有多少个长度为m的DNA序列和给定序列的LCS为0,1,2... ...
- 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 ...
随机推荐
- Canvas在移动端设备上模糊出现锯齿边
在绘制的过程中画布内容的实际大小是根据 canvas 的 width 与 height 属性设置的,而 style 或者CSS设置的width 与 height 只是简单的对画布进行缩放. canva ...
- 20145209 2016-2017-2 《Java程序设计》第2周学习总结
20145209 2016-2017-2 <Java程序设计>第2周学习总结 教材学习内容总结 git log 命令来查看 :提交历史 查看当前所处位置: pwd git 版本控制 tou ...
- POJ2505 A multiplication game(博弈)
题意 开始时$p = 1$,每次可以乘$2 - 9$,第一个使得$p \geqslant n$的人赢 问先手是否必胜 $1 <n <4294967295$ Sol 认真的推理一波. 若当前 ...
- 成都Uber优步司机奖励政策(1月26日)
滴快车单单2.5倍,注册地址:http://www.udache.com/ 如何注册Uber司机(全国版最新最详细注册流程)/月入2万/不用抢单:http://www.cnblogs.com/mfry ...
- VIO 初始化小结 - 10.17
最近几个月忙于博士毕业,找工作一直没有继续更新博客,希望以这一篇开始,每个月能够继续有几篇总结博客. 首先review一下比较著名的vio系统 Tightly coupled EKF: mainly ...
- 如何去除Eclipse下的JS引入报错(类似Syntax error on token...的异常信息)
在Eclipse下引入外部JS文件,比如Jquery.js,经常会出现如下异常信息: 去除该异常方法: 1. 去掉Eclipse的JS验证 Windws---->Preferences----& ...
- 收集、分析线上日志数据实战——ELK
本文来自网易云社区 作者:田躲躲 用户行为统计(User Behavior Statistics, UBS)一直是互联网产品中必不可少的环节,也俗称埋点.对于产品经理,运营人员来说,埋点当然是越多,覆 ...
- Visual Studio 2015 Test Explorer does not show anything
Problem After install Visual Studio 2015 community and NUnit Test Adapter, I cannot find test cases ...
- hdu1527取石子游戏(威佐夫博弈)
取石子游戏 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Submi ...
- Appium-原理、设置
Appium是支持跨平台的移动端自动化测试框架. 下面介绍下Appium的具体工作流程: 首先,Appium server 默认监听4723端口,监听客户端的命令. 客户端指的是 我们编写的自动化测试 ...