[DP套DP] BZOJ 3864 Hero meet devil

来源:互联网 发布:淘宝购买送货入户 编辑:程序博客网 时间:2024/05/18 04:00

我们令fi,j表示TiSj的LCS
然后我们发现 fi,jfi,j1[0,1] 这个东西可以状压
预处理所有转移 然后DP

#include<cstdio>#include<cstdlib>#include<algorithm>#include<cstring>#define cl(x) memset(x,0,sizeof(x))using namespace std;int n,m,a[20];int tr[1<<15][4],cnt[1<<15];int f[20],g[20];inline void Pre(){  for (int s=0;s<(1<<n);s++){    for (int i=1;i<=n;i++) f[i]=f[i-1]+(s>>(i-1)&1);    cnt[s]=f[n];    for (int k=0;k<4;k++){      for (int i=1;i<=n;i++){    g[i]=max(g[i-1],f[i]);    if (k==a[i])      g[i]=max(g[i],f[i-1]+1);      }      int t=0;      for (int i=1;i<=n;i++)    t+=(g[i]-g[i-1])<<(i-1);      tr[s][k]=t;    }  }}const int P=1e9+7;int F[2][1<<15];inline void add(int &x,int y){  x+=y; if (x>=P) x-=P;}int main(){  int T; char s[20];  freopen("t.in","r",stdin);  freopen("t.out","w",stdout);  scanf("%d",&T);  while (T--){    scanf("%s",s+1); n=strlen(s+1); scanf("%d",&m);    for (int i=1;i<=n;i++) a[i]=s[i]=='A'?0:(s[i]=='G'?1:(s[i]=='C'?2:3));    Pre();    int t=0; memset(F[t],0,sizeof(int)*(1<<n));    F[t][0]=1;    for (int i=1;i<=m;i++,t^=1){      memset(F[t^1],0,sizeof(int)*(1<<n));      for (int j=0;j<(1<<n);j++)    for (int k=0;k<4;k++)      add(F[t^1][tr[j][k]],F[t][j]);    }    int ans[20]={0};    for (int j=0;j<(1<<n);j++)      add(ans[cnt[j]],F[t][j]);    for (int i=0;i<=n;i++)      printf("%d\n",ans[i]);  }  return 0;}
原创粉丝点击