• 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<cstring>
    const int N=15,P=1000000007;
    int T,n,m,i,j,k,x,a[N+1],f[N+1],g[N+1],v[1<<N][4],F[2][1<<N],ans[N+1];char s[N+1];
    inline void up(int&a,int b){a+=b;if(a>=P)a-=P;}
    void work(){
      scanf("%s%d",s+1,&m);n=std::strlen(s+1);
      for(i=1;i<=n;i++){
        if(s[i]=='A')a[i]=0;
        if(s[i]=='G')a[i]=1;
        if(s[i]=='T')a[i]=2;
        if(s[i]=='C')a[i]=3;
      }
      for(i=0;i<1<<n;i++){
        for(j=0;j<n;j++)f[j+1]=f[j]+(i>>j&1);
        for(j=0;j<4;j++){
          for(k=1;k<=n;k++)if(a[k]==j)g[k]=f[k-1]+1;else g[k]=f[k]>g[k-1]?f[k]:g[k-1];
          for(v[i][j]=0,k=1;k<=n;k++)if(g[k]>g[k-1])v[i][j]|=1<<(k-1);
        }
      }
      for(j=0;j<1<<n;j++)F[0][j]=0;
      for(F[0][0]=1,i=x=0;i<m;i++,x^=1){
        for(j=0;j<1<<n;j++)F[x^1][j]=0;
        for(j=0;j<1<<n;j++)if(F[x][j])for(k=0;k<4;k++)up(F[x^1][v[j][k]],F[x][j]);
      }
      for(i=0;i<=n;i++)ans[i]=0;
      for(i=0;i<1<<n;i++)up(ans[__builtin_popcount(i)],F[x][i]);
      for(i=0;i<=n;i++)printf("%d
    ",ans[i]);
    }
    int main(){
      for(scanf("%d",&T);T--;work());
      return 0;
    }
    

      

  • 相关阅读:
    poj 图算法
    类里二级排序函数使用
    数学题目(高斯消元)
    多校联合比赛部分题目
    poj 3007 & poj 3096
    优先队列
    hdu 各种 A + B
    几道数学题目
    今天下午
    Java常用的几种设计模式
  • 原文地址:https://www.cnblogs.com/clrs97/p/4799463.html
Copyright © 2020-2023  润新知