Learn a DP set DP
#include <cstdio> #include <iostream> #include <algorithm> #include <cstring> using namespace St
D
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; }