我们令
fi,j
表示
Ti
和
Sj
的LCS
然后我们发现
fi,j−fi,j−1∈[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;
}