bzoj3864 题解

dp套dp

/*
{
######################
#       Author       #
#        Gary        #
#        2021        #
######################
*/
#include<bits/stdc++.h>
#define rb(a,b,c) for(int a=b;a<=c;++a)
#define rl(a,b,c) for(int a=b;a>=c;--a)
#define LL long long
#define IT iterator
#define PB push_back
#define II(a,b) make_pair(a,b)
#define FIR first
#define SEC second
#define FREO freopen("check.out","w",stdout)
#define rep(a,b) for(int a=0;a<b;++a)
#define SRAND mt19937 rng(chrono::steady_clock::now().time_since_epoch().count())
#define random(a) rng()%a
#define ALL(a) a.begin(),a.end()
#define POB pop_back
#define ff fflush(stdout)
#define fastio ios::sync_with_stdio(false)
#define check_min(a,b) a=min(a,b)
#define check_max(a,b) a=max(a,b)
using namespace std;
//inline int read(){
//    int x=0;
//    char ch=getchar();
//    while(ch<'0'||ch>'9'){
//        ch=getchar();
//    }
//    while(ch>='0'&&ch<='9'){
//        x=(x<<1)+(x<<3)+(ch^48);
//        ch=getchar();
//    }
//    return x;
//}
const int INF=0x3f3f3f3f;
typedef pair<int,int> mp;
/*}
*/
const int MOD=1e9+7;
int dp[2][1<<16];
int tran[1<<16][4];
int n;
int rest[16];
char c[4]={'A','G','C','T'};
void solve(){
	memset(dp,0,sizeof(dp));
	memset(rest,0,sizeof(rest));
	string t;
	cin>>t>>n;
	dp[0][0]=1;
	rep(mask,1<<(t.length()+1)){
		rep(k,4){
			int f[16]={0};
			rep(j,t.length()+1) f[j]=(j? f[j-1]:0)+((mask>>j)&1);
			int nf[16]={0};
			rep(j,t.length()+1){
				nf[j]=f[j];
				if(j)
				check_max(nf[j],nf[j-1]);
				if(j&&t[j-1]==c[k]){
					check_max(nf[j],f[j-1]+1);
				}
			}
			int nmask=0;
			rl(j,t.length(),1) nf[j]=nf[j]-nf[j-1],nmask|=(nf[j])<<j;
			tran[mask][k]=nmask;
		}
	}
	rb(i,1,n){
		memset(dp[i&1],0,sizeof(dp[i&1]));
		rep(mask,1<<(t.length()+1)){
			if(!dp[(i&1)^1][mask]) continue;
			rep(k,4)
			{
				int nmask=tran[mask][k];
				dp[i&1][nmask]+=dp[(i&1)^1][mask];
				dp[i&1][nmask]%=MOD;
			}
		}
	}
	rep(mask,1<<(t.length()+1)){
		int _=__builtin_popcount(mask);
		rest[_]+=dp[n&1][mask];
		rest[_]%=MOD;
	} 
	rep(i,t.length()+1){
		printf("%d\n",rest[i]);
	}
}
int main(){
	int T;
	scanf("%d",&T);
	while(T--) solve();	
	return 0;
}
/*
5
GTTACCGCGCGAGAG
1000
TCCGGAAGTCACAGT
1000
GGTACAACTTATCAG
1000
CTCTTAAATCCAGGC
1000
AATCGAAGGTCGTAT
1000


*/

posted @ 2021-02-20 15:45  WWW~~~  阅读(50)  评论(0编辑  收藏  举报