zoukankan      html  css  js  c++  java
  • [BZOJ3864]Hero meet devil

    CXXXIV.[BZOJ3864]Hero meet devil

    我们不妨从最trival的LCS问题上想起:暴力的LCS求法是什么?

    \(f(i,j)\) 表示一个串(不妨设为本题中要填的字符串 \(T\))的前 \(i\) 位与另一个串(即题目中给出的 \(S\))的前 \(j\) 位所构成的串的LCS。则 \(f(i,j)=\max\Big\{f(i,j-1),f(i-1,j),f(i-1,j-1)+[t_i=s_j]\Big\}\)

    因为 \(|S|\) 很小,所以我们可以考虑设 \(f(i,\mathbb{S})\) 表示当前填到 \(T\) 的第 \(i\) 位,且 \(\mathbb{S}\) 中通过某种方式储存了 \(f(i,0)\sim f(i,|S|)\) 全部的DP值,满足此种情形的串的方案数。下面考虑怎么搞出 \(\mathbb{S}\)

    明显,对于 \(f(i,0\sim|S|)\) 来说,相邻两个数的差至多为 \(1\),这一点可以直接从DP式上看出。于是我们可以状压其差分数组,即可实现由数组到状态的一一映射。这之后,我们只需预处理出对于每个 \(\mathbb S\) 对应的状态,其之后添加 A,G,C,T 四个字符会分别到达哪个新状态即可。然后直接DP就行了。

    这种手法被称作“DP on DP”,因为DP状态中储存了另一种更简单的DP的数组。可以发现,简单DP的数组压缩后得到了一张自动姬。

    时间复杂度 \(O(m2^n)\)

    代码:

    #include<bits/stdc++.h>
    using namespace std;
    const int mod=1e9+7;
    int T,n,m,f[2][1<<15],lim,t[20],a[20],b[20],res[20],trans[1<<15][4];
    char s[20];
    int main(){
    	scanf("%d",&T);
    	while(T--){
    		scanf("%s%d",s+1,&m),n=strlen(s+1),lim=1<<n;
    		for(int i=1;i<=n;i++){
    			if(s[i]=='A')t[i]=0;
    			if(s[i]=='G')t[i]=1;
    			if(s[i]=='C')t[i]=2;
    			if(s[i]=='T')t[i]=3;
    		}
    		for(int j=0;j<lim;j++){
    			for(int k=0;k<n;k++)a[k+1]=a[k]+((j>>k)&1);
    			for(int c=0;c<4;c++){
    				for(int k=1;k<=n;k++)b[k]=max({a[k-1]+(t[k]==c),a[k],b[k-1]});
    				trans[j][c]=0;
    				for(int k=0;k<n;k++)trans[j][c]|=(b[k+1]-b[k])<<k;
    			}
    		}
    		memset(f,0,sizeof(f)),f[0][0]=1;
    		for(int i=0;i<m;i++){
    			memset(f[!(i&1)],0,sizeof(f[!(i&1)]));
    			for(int j=0;j<lim;j++)for(int k=0;k<4;k++)(f[!(i&1)][trans[j][k]]+=f[i&1][j])%=mod;
    		}
    //		for(int i=0;i<=m;i++){for(int j=0;j<lim;j++)printf("%d ",f[i][j]);puts("");}
    		for(int i=0;i<lim;i++)(res[__builtin_popcount(i)]+=f[m&1][i])%=mod;
    		for(int i=0;i<=n;i++)printf("%d\n",res[i]),res[i]=0;
    	}
    	return 0;
    }
    

  • 相关阅读:
    volumetric rendering ---fog/ light/cloud
    strand based hair rendering
    一个相当复杂的延迟管线
    wenti
    ubunt tmux X Error of failed request
    Python编程练习题
    ubuntu15.04 安装 pylab失败,先记下来,漫漫看
    翻译:打造基于Sublime Text 3的全能python开发环境
    关于web2py外网访问,图形界面不显示等问题的解决办法
    yii2中gii外网访问的配置方法
  • 原文地址:https://www.cnblogs.com/Troverld/p/14601544.html
Copyright © 2011-2022 走看看