学一发DP套DP
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
using namespace std;
const int N=1<<16|5,P=1e9+7;
int T,n,m;
char a[20],b[5]={'A','T','C','G'};
int f[2][N],g[N][5],w[20],v[20];
inline int chans(int S,int c){
if(~g[S][c]) return g[S][c];
w[0]=v[0]=0;
for(int i=1;i<=n;i++)
w[i]=w[i-1]+(S>>(i-1)&1);
for(int i=1;i<=n;i++){
v[i]=max(v[i-1],w[i]);
if(a[i]==b[c]) v[i]=max(v[i],w[i-1]+1);
}
int ret=0;
for(int i=1;i<=n;i++)
if(v[i]>v[i-1]) ret|=1<<i-1;
return g[S][c]=ret;
}
int size[N];
inline void add(int &x,int y){ (x+=y)%=P; }
int main(){
scanf("%d",&T);
for(int i=1;i<(1<<15);i++) size[i]=size[i>>1]+(i&1);
while(T--){
scanf("%s%d",a+1,&m); n=strlen(a+1);
memset(g,-1,sizeof(g));
int *F=f[0],*G=f[1]; F[0]=1;
for(int S=1;S<(1<<n);S++) F[S]=0;
for(int i=1;i<=m;i++,swap(F,G)){
for(int S=0;S<(1<<n);S++) G[S]=0;
for(int S=0;S<(1<<n);S++){
if(!F[S]) continue;
for(int c=0;c<4;c++)
add(G[chans(S,c)],F[S]);
}
}
for(int i=0;i<=n;i++) w[i]=0;
for(int S=0;S<(1<<n);S++) add(w[size[S]],F[S]);
for(int i=0;i<=n;i++) printf("%d\n",w[i]);
}
return 0;
}