zoukankan      html  css  js  c++  java
  • 【BZOJ3864】Hero meet devil(DP套DP)

    点此看题面

    大致题意: 给定一个字符串,对于每一个(i),问有多少由"A","G","T","C"组成的长度为(m)的字符串和给定串的最长公共子序列长度为(i)

    双倍经验

    可以去看看【洛谷4590】[TJOI2018] 游园会,就会发现与那题相比此题甚至还要少一个限制。

    这里直接给出代码了。

    代码

    #include<bits/stdc++.h>
    #define Tp template<typename Ty>
    #define Ts template<typename Ty,typename... Ar>
    #define Reg register
    #define RI Reg int
    #define Con const
    #define CI Con int&
    #define I inline
    #define W while
    #define M 15
    #define X 1000000007
    #define Inc(x,y) ((x+=(y))>=X&&(x-=X))
    using namespace std;
    int n,l,s[M+5];char st[M+5];
    class LCS_Automation
    {
    	private:
    		int lim,a[M+5],f[M+5],S[1<<M][4],cnt[1<<M],dp[2][1<<M];
    		I void Extend(CI x)//求出x的后继状态
    		{
    			RI i;for(i=0;i^l;++i) a[i+1]=a[i]+((x>>i)&1);//解码
    			RI j,t;for(i=0;i^4;++i)//枚举加入字符
    			{
    				for(j=1;j<=l;++j) f[j]=max(max(a[j],f[j-1]),a[j-1]+(s[j]==i));//DP
    				for(t=j=0;j^l;++j) t|=(f[j+1]-f[j])<<j;S[x][i]=t;//状压差值
    			}
    		}
    	public:
    		I void Build() {lim=1<<l;for(RI i=0;i^lim;++i) Extend(i);}//建立LCS自动机
    		int ans[M+5];I void DP()//LCS自动机上DP
    		{
    			#define Cls(t) memset(dp[t],0,sizeof(dp[t]))
    			RI i,j,k,t;for(Cls(0),dp[0][0]=1,t=i=0;i^n;++i,t^=1)//注意滚存
    				for(Cls(t^1),j=0;j^lim;++j) for(k=0;k^4;++k) Inc(dp[t^1][S[j][k]],dp[t][j]);//枚举加入字符转移
    			for(memset(ans,0,sizeof(ans)),i=0;i^lim;++i)//显然cnt[i]就是状态i的LCS
    				cnt[i]=cnt[i>>1]+(i&1),Inc(ans[cnt[i]],dp[t][i]);//统计答案
    		}
    }A;
    int main()
    {
    	RI Tt,i;scanf("%d",&Tt);W(Tt--)
    	{
    		scanf("%s%d",st+1,&n),l=strlen(st+1);
    		for(i=1;i<=l;++i) s[i]=st[i]^'A'?(st[i]^'G'?(st[i]^'T'?3:2):1):0;//把字符改为数码
    		for(A.Build(),A.DP(),i=0;i<=l;++i) printf("%d
    ",A.ans[i]);//建自动机,然后自动机上DP
    	}return 0;
    }
    
  • 相关阅读:
    select,epoll,poll比较(网络资源总结)
    c++(重载、覆盖、隐藏)
    TCP状态转换图
    TCP心跳 | TCP keepAlive
    回车、换行、空格的ASCII码值—(附ASCII码表)
    C++ dlopen mini HOWTO 一篇非常好的介绍
    shell十三问
    linux IPC消息队列 的内核限制
    C++ string 类常用函数
    const用法的解惑
  • 原文地址:https://www.cnblogs.com/chenxiaoran666/p/BZOJ3864.html
Copyright © 2011-2022 走看看