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\)为止的最长公共子序列,那么转移为

\[
LCS(i,j)=\max
\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[i][to[s][k]]+=f[i-1][s](k=A,T,G,C)\]

边界为\(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;
}

原文地址:https://www.cnblogs.com/bztMinamoto/p/10534010.html

时间: 2024-10-06 00:54:41

bzoj 3864: Hero meet devil(dp套dp)的相关文章

[hdu 4899]14年多校第四场C Hero meet devil 状压DP

Time Limit: 16000/8000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others) Total Submission(s): 122    Accepted Submission(s): 49 Problem 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

[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 lo

[CTSC2017]最长上升自序列(伪题解)(树状数组+DP套DP+最小费用最大流+Johnson最短路+Yang_Tableau)

部分分做法很多,但每想出来一个也就多5-10分.正解还不会,下面是各种部分分做法: Subtask 1:k=1 LCS长度最长为1,也就是说不存在j>i和a[j]>a[i]同时成立.显然就是一个LDS,树状数组直接求即可. Subtask 2:k=2 最多两个,也就是可以由两个LCS拼起来,f[i][j]表示第一个LCS以i结尾,第二个以j结尾的方案数,转移显然. Subtask 3:k=2 树状数组优化DP,复杂度由$O(n^3)$降为$O(n^2 \log n)$ Subtask 4,5:

动态dp和dp套dp

概述 这是两类特别的\(dp\)种类,分别是带修改的\(dp\),与\(dp\)过程本身息息相关的\(dp\) 动态dp 概述 一些简单的\(dp\)如果带修改怎么办 如果状态是普通设法,修改一个值的话包含这个值的所有情况都会被改,均摊\(O(n)\) 一种粗暴的看法,我们可以让所有状态包含的值均摊,比如用倍增划分区间的设法,让均摊被包含的状态数变为\(\log\),但这个说法很模糊,我们并不知道什么状态可以倍增 事实上,这牵扯到一个很重要的东西,"转移"这个运算有结合律否 如果有的话

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

http://www.lydsy.com/JudgeOnline/problem.php?id=3864 题意: 给你一个DNA序列,求有多少个长度为m的DNA序列和给定序列的LCS为0,1,2.... 求LCS方式:f[i][j]=max(f[i-1][j],f[i][j-1],f[i-1][j-1]*(s[i]==t[j])) 固定了i,相邻的j的f[i][j]值最多相差1 dp[i][j] 表示长度为i的DNA序列,将“f[ |S| ][j+1]是否比f[ |S| ][j] 大1” 这个状

BZOJ3864 : Hero meet devil

考虑计算LCS的DP过程,设f[i][j]表示T串的前i项与S串的前j项的LCS,则 若T[i]==S[j],则f[i][j]=f[i-1][j-1]+1 否则f[i][j]=max(f[i-1][j],f[i][j-1]) 对于固定的i,f[i][j]只可能为f[i][j-1]或f[i][j-1]+1,把这个差值用二进制表示成状态. 先预处理出每个状态后面加了一个字符后会到达什么状态,然后进行状压DP即可. 时间复杂度$O(m2^n)$. #include<cstdio> #include&

BZOJ 1042 硬币购物(完全背包+DP)

题目链接:http://61.187.179.132/JudgeOnline/problem.php?id=1042 题意:给出四种面值的硬币c1,c2,c3,c4.n个询问.每次询问用d1.d2.d3.d4个相应的硬币能够拼出多少种总和为s? 思路:(1)首先,用完全背包求出f[i]表示四种硬币的数量无限制拼出i的方案数. (2)接着我们来理解 x=f[s]-f[s-(d1+1)*c1]的含义:x表示c1硬币的数量不超过d1个而其他三种硬币的数量不限制拼成s的方案数.我们举着例子来说明, 假设

【POJ 2750】 Potted Flower(线段树套dp)

[POJ 2750] Potted Flower(线段树套dp) Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 4566   Accepted: 1739 Description The little cat takes over the management of a new park. There is a large circular statue in the center of the park, surrou

BZOJ 1855 股票交易(单调队列优化DP)

题目链接:http://61.187.179.132/JudgeOnline/problem.php?id=1855 题意:最近lxhgww又迷上了投资股票, 通过一段时间的观察和学习,他总结出了股票行情的一些规律. 通过一段时间的观察,lxhgww预测到了未来T天内某只股票的走势,第i天的股票买入价为每股APi,第i天的股票卖出价为每股BPi(数据保证对于每 个i,都有APi>=BPi),但是每天不能无限制地交易,于是股票交易所规定第i天的一次买入至多只能购买ASi股,一次卖出至多只能卖出BS