HDU4899 Hero meet devil DP套DP
陈老师的题QwQ
原题链接
题目大意
有两个字符串\(S\)和\(T\)(都只能由'A','C','G','T'这四个字符组成),\(S\)已知\(T\)未知,还知道\(S\)的长度为\(m\)。求满足\(Len(LCS(S,T))=L,1\leqslant L\leqslant |T|\)的\(S\)的个数
先想想若\(S\)已知怎么做。一个简单的\(DP\)就能解决,设\(dp[i][j]\)表示\(S\)到\(i\)位置,\(T\)到\(j\)位置时\(LCS\)的长度:
1.若\(S[i]==T[j]\),则\(dp[i][j]=max(dp[i-1][j-1]+1,max(dp[i-1][j],dp[i][j-1]))\)
2.否则\(dp[i][j]=max(dp[i-1][j],dp[i][j-1])\)
然后考虑倒过来怎么做,看一下数据范围,可能状压?设\(f[i][state]\)表示\(T\)填到第\(i\)位,\(dp[?][i]\)在\(Len(S)+1\)进制下的表示时的方案数,再令\(g[state][c]\)表示状态是\(state\)时再加一个字符\(c\)后的\(state\)是多少。\(g\)数组可以预处理一下,然后\(f\)就好转移了:
\(f[i][g[state][c]]=f[i][g[state][c]]+f[i-1][state]\)
这样的话空间显然会炸,一个显然的性质,\(dp[i][j]\)只有可能是\(dp[i-1][j]\)或\(dp[i-1][j]+1\),我们把差分数组在二进制下压一下就行了
预处理时间复杂度\(O(4*n*2^{Len(S)})\),转移的时间复杂度为\(O(4*m*2^{Len(S)})\),空间复杂度\(\theta (m*2^{Len(S)}+4*2^{Len(S)})\)
代码(预处理参考了自为风月马前卒大佬的博客):
#include <bits/stdc++.h>
#define MOD 1000000007
using namespace std;
int kase;
string S;
char ch[4] = {'A', 'C', 'G', 'T'};
int n, m, tmp[2][20], lim, f[1001][32800], g[32800][4], ans[20];
int lowbit(int x) {
return x&-x;
}
int popcount(int x) {
int cnt = 0;
while(x) cnt++, x -= lowbit(x);
return cnt;
}
int calc(int state, char c) {
for(int i = 1; i <= n; ++i) tmp[0][i] = tmp[0][i-1]+((state>>i-1)&1);
int ret = 0;
for(int i = 1; i <= n; ++i)
{
int t = 0;
if(c == S[i-1]) t = tmp[0][i-1]+1;
t = max(t, max(tmp[1][i-1], tmp[0][i]));
tmp[1][i] = t;
}
for(int i = 1; i <= n; ++i) ret += (1<<i-1)*(tmp[1][i]-tmp[1][i-1]);
return ret;
}
int main() {
cin >> kase;
for(int i = 1; i <= kase; ++i) {
cin >> S >> m;
n = S.length();
lim = (1<<n)-1;
memset(f, 0, sizeof f), memset(ans, 0, sizeof ans);
f[0][0] = 1;
for(int i = 0; i <= lim; ++i)
for(int j = 0; j < 4; ++j) g[i][j] = calc(i, ch[j]);
for(int i = 1; i <= m; ++i)
for(int j = 0; j <= lim; ++j)
for(int k = 0; k < 4; ++k)
f[i][g[j][k]] = (f[i][g[j][k]]+f[i-1][j])%MOD;
for(int i = 0; i <= lim; ++i) ans[popcount(i)] = (ans[popcount(i)]+f[m][i])%MOD;
for(int i = 0; i <= n; ++i) cout << ans[i] << endl;
}
return 0;
}
HDU4899 Hero meet devil DP套DP的更多相关文章
- hdu4899 Hero meet devil
题目链接 题意 给出一个长度字符串\(T\),其中只包含四种字符\((A,C,G,T)\),需要找一个字符串\(S\),使得\(S\)的长度为\(m\),问\(S\)和\(T\)的\(lcs\)为\( ...
- HDU 4899 Hero meet devil (状压DP, DP预处理)
题意:给你一个基因序列s(只有A,T,C,G四个字符,假设长度为n),问长度为m的基因序列s1中与给定的基因序列LCS是0,1......n的有多少个? 思路:最直接的方法是暴力枚举长度为m的串,然后 ...
- BZOJ 3864 Hero meet devil (状压DP)
最近写状压写的有点多,什么LIS,LCSLIS,LCSLIS,LCS全都用状压写了-这道题就是一道状压LCSLCSLCS 题意 给出一个长度为n(n<=15)n(n<=15)n(n< ...
- bzoj 3864: Hero meet devil [dp套dp]
3864: Hero meet devil 题意: 给你一个只由AGCT组成的字符串S (|S| ≤ 15),对于每个0 ≤ .. ≤ |S|,问 有多少个只由AGCT组成的长度为m(1 ≤ m ≤ ...
- 【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 ...
- DP套DP
DP套DP,就是将内层DP的结果作为外层DP的状态进行DP的方法. [BZOJ3864]Hero meet devil 对做LCS的DP数组差分后状压,预处理出转移数组,然后直接转移即可. tr[S] ...
- [模板] dp套dp && bzoj5336: [TJOI2018]party
Description Problem 5336. -- [TJOI2018]party Solution 神奇的dp套dp... 考虑lcs的转移方程: \[ lcs[i][j]=\begin{ca ...
- BZOJ 3864 Hero meet devil 超详细超好懂题解
题目链接 BZOJ 3864 题意简述 设字符集为ATCG,给出一个长为\(n(n \le 15)\)的字符串\(A\),问有多少长度为\(m(m \le 1000)\)的字符串\(B\)与\(A\) ...
- luogu 4158 粉刷匠 dp套dp
dp套dp 每个木板是个递推的dp,外部是个分组背包 #include<bits/stdc++.h> #define rep(i,x,y) for(register int i=x;i&l ...
随机推荐
- 第二次上机,ASP内置对象的使用
3.新建Reg.asp文档,参照1中的Reg.html,通过VBScript服务器端脚本代码实现 ”班级” Select表单的自动生成,如下所示: 注:通过循环语句,采用Response.Write命 ...
- Snapde和Excel、PowerPivot、WPS打开超大CSV文件性能比较
Snapde,一个专门为编辑超大型数据量CSV文件而设计的单机版电子表格软件:它运行的速度非常快,反应非常灵敏. 我们拿四份文件进行测试,对比一下他们打开大文件的性能:loan_theme_ids.c ...
- 未找到导入的项目“C:\Program Files (x86)\MSBuild\Microsoft\VisualStudio\v14.0\DotNet\Microsoft.DotNet.Props”
未找到导入的项目“C:\Program Files (x86)\MSBuild\Microsoft\VisualStudio\v14.0\DotNet\Microsoft.DotNet.Props” ...
- 我喜欢的vs code快捷键for mac
mac上的快捷键,尽量是像我用vs studio上靠近. cmd+K+S: 显示快捷键列 cmd+shift+p: 系统配置命令行 cmd+p:项目中文件列表,选择文件 cmd+shift+o:当前文 ...
- go打造以太坊合约测试框架
传送门: 柏链项目学院 1 以太坊智能合约编译 以太坊智能合约编写使用solidity语言,一般情况下我们会在remix环境下进行编译测试,在线环境相对比较稳定.如果不想用在线环境,那我们就需要自己动 ...
- 【转】Dockerfile详解
Dockerfile详解 https://blog.csdn.net/wo18237095579/article/details/80540571 --------------------- 作者:大 ...
- DNS域名解析过程,域名的认识
DNS域名解析过程 参考知乎:https://www.zhihu.com/question/23042131 当你通过浏览器输入url访问资源时,会请求DNS解析域名成对应的IP地址,由IP地址在去与 ...
- openwrt 里LUA程序怎么获取POST数据?
https://www.zhihu.com/question/31579325 作者:齐葛链接:https://www.zhihu.com/question/31579325/answer/28342 ...
- Shell中数组的使用
数组是一个很有用的数据结构,经常使用的功能有初始化,遍历,查找,获取数组长度等操作 一.初始化 小括号中使用空格分开的数据结构就是一个数组,也可使用下标添加元素 arr=(1 'nice' '2day ...
- 毕业设计5:基于MicroPython的智能火灾报警器系统的设计与实现
随着现代家庭用火.用电量的增加,家庭火灾发生的频率越来越高.家里一旦发生火灾,如果出现扑救不及时.灭火器材缺乏.以及在场人惊慌失措.逃生迟缓等不利情况下,最终就会导致产生重大的生命财产的损失. 消防部 ...