bzoj 3864: Hero meet devil(dp套dp)
题面
给你一个只由\(AGCT\)组成的字符串\(S (|S| ≤ 15)\),对于每个\(0 ≤ .. ≤ |S|\),问
有多少个只由\(AGCT\)组成的长度为\(m(1 ≤ m ≤ 1000)\)的字符串\(T\),使得\(LCS(T,S)=i\)?
题解
老早就听说这个叫做\(dp\ of\ dp\)的神仙了……然而一直没学……
我们先考虑\(LCS\)是怎么转移的,设\(LCS(i,j)\)表示第一个串到\(i\),第二个串到\(j\)为止的最长公共子序列,那么转移为
\begin{cases}
LCS(i-1,j-1)+1 &S[i]=T[j]\\
LCS(i,j-1)\\
LCS(i-1,j)
\end{cases}
\]
然后我们发现\(LCS(i,j)\)的值和\(LCS(i,j-1)\)的值相差最多不会超过\(1\)
那么我们把数组的第二维差分一下,再状压成一个二进制序列,然后我们就可以预处理出\(to[s][k]\)表示当前\(LCS\)状态为\(s\),加的下一个字符为\(k\),可以到达的\(LCS\)状态是什么
然后设\(f[i][s]\)表示当前在第\(i\)个位置,此时\(LCS\)状态为\(s\)的方案数
那么转移方程就是
\]
边界为\(f[0][0]=1\)
//minamoto
#include<bits/stdc++.h>
#define R register
#define fp(i,a,b) for(R int i=(a),I=(b)+1;i<I;++i)
#define fd(i,a,b) for(R int i=(a),I=(b)-1;i>I;--i)
#define go(u) for(int i=head[u],v=e[i].v;i;i=e[i].nx,v=e[i].v)
template<class T>inline bool cmax(T&a,const T&b){return a<b?a=b,1:0;}
using namespace std;
const char T[15]={"ATGC"};const int N=(1<<15)+5,P=1e9+7;
inline void Add(R int &x,R int y){(x+=y)>=P?x-=P:0;}
char S[19];int to[N][4],sz[N],f[2][N],ans[1005];
int n,m,lim,t;
void init(){
static int d[19],g[19];
fp(s,0,lim-1){
sz[s]=sz[s>>1]+(s&1);
fp(j,0,n-1)d[j+1]=d[j]+(s>>j&1);
fp(k,0,3){
fp(j,1,n){
g[j]=max(g[j-1],d[j]);
T[k]==S[j]?cmax(g[j],d[j-1]+1):0;
}
to[s][k]=0;
fp(j,0,n-1)g[j+1]-g[j]?(to[s][k]|=(1<<j)):0;
}
}
}
int main(){
// freopen("testdata.in","r",stdin);
int cas;scanf("%d",&cas);
while(cas--){
scanf("%s%d",S+1,&m),n=strlen(S+1),lim=(1<<n);
init(),memset(ans,0,4*(n+1)),memset(f,0,sizeof(f));
f[0][0]=1,t=0;
for(R int i=1;i<=m;++i,t^=1){
memset(f[t^1],0,4*lim);
fp(s,0,lim-1)fp(k,0,3)Add(f[t^1][to[s][k]],f[t][s]);
}
fp(s,0,lim-1)Add(ans[sz[s]],f[t][s]);
fp(i,0,n)printf("%d\n",ans[i]);
}
return 0;
}
bzoj 3864: Hero meet devil(dp套dp)的更多相关文章
- 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 ≤ ...
- BZOJ 3864 Hero meet devil 超详细超好懂题解
题目链接 BZOJ 3864 题意简述 设字符集为ATCG,给出一个长为\(n(n \le 15)\)的字符串\(A\),问有多少长度为\(m(m \le 1000)\)的字符串\(B\)与\(A\) ...
- bzoj 3864: Hero meet devil
bzoj3864次元联通们 第一次写dp of dp (:з」∠) 不能再颓废啦 考虑最长匹配序列匹配书转移 由于dp[i][j]的转移可由上一行dp[i-1][j-1],dp[i-1][j],dp[ ...
- BZOJ 3864 Hero Meets Devil
题目大意 给定一个由AGCT组成的串\(t\), 求对于所有的\(L \in [1, |t|]\), 有多少个由AGCT组成的串\(s\)满足\(LCS(s, t) = L\). Solution 传 ...
- HDU 4899 Hero meet devil (状压DP, DP预处理)
题意:给你一个基因序列s(只有A,T,C,G四个字符,假设长度为n),问长度为m的基因序列s1中与给定的基因序列LCS是0,1......n的有多少个? 思路:最直接的方法是暴力枚举长度为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 ...
随机推荐
- python对裤子进行一个查询
前言: 获取到一个数据库,使用python对其 进简单的查询 代码: import time print('开房记录查询') def chax(): g=input('请输入要查询的>>& ...
- leetcode811
class Solution { public: void SplitString(const string& s, vector<string>& v, const st ...
- string的深入理解
本文只是个人总结见解,勿喷 首先肯定的是string是引用类型 string s_a = "yhc"; string s_b = s_a; if(s_a.Equals(s_b)) ...
- Oracle-11g 中当执行 DBMS_STATS 时,因数据泵外部表文件缺失 Alert Log 告警 "ORA-20011、ORA-29913" 以及 "KUP-XXXXX"错误
:first-child { margin-top: 0; } blockquote > :last-child { margin-bottom: 0; } img { border: 0; m ...
- Leetcode:Task Scheduler分析和实现
题目大意:提供k个任务,这些任务没有依赖关系(即可以任意调度).CPU完成一个任务需要耗时一个时间片段,当执行完一个任务后,相同的任务必须在n个时间片段才能得以执行.请问CPU通过调度最快能在多少时间 ...
- Junit问题01 利用 @Autowired 注入失效问题
1 利用 @Autowired 注入失效问题 1.1 问题描述 在使用Junit作为测试框架的单元测试中,直接了用@Autowired记性依赖注入时总是注入失败 1.2 问题原因 在测试类中没有设定上 ...
- c语言学习笔记-if语句块一定要加分号
if(a>6) printf("hello");//语句1 printf("world");//语句2 当a>6的时候,执行的分支语句是语句1,而不 ...
- 487C Prefix Product Sequence
传送门 题目大意 分析 因为n为质数所以i-1的逆元唯一 因此ai唯一 代码 #include<iostream> #include<cstdio> #include<c ...
- Python3 使用requests库读取本地保存的cookie文件实现免登录访问
1. 读取selenium模块保存的本地cookie文件来访问知乎 读取http://www.cnblogs.com/strivepy/p/9233389.html保存的本地cookie来访问知乎的 ...
- [GO]append的扩容
package main import "fmt" func main() { s := make([], ) oldcap := cap(s) ; i < ; i++{ s ...