分析:dp[i][j]表示当前为i长度,长度为k的后缀状态,有多少个串。考虑一下k和k+1长度的串是否为回文串即可
代码:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <map>
#include <vector>
#include <queue>
#include <set>
#define FRER() freopen("in.txt","r",stdin)
#define FREW() freopen("out.txt","w",stdout)
#define go int T;cin>>T;for(int kase=0;kase<T;kase++)
#define debug cout<<"****************"<<endl
#define lowbit(x) x&(-x)
#define eps 1e-6
#define mod 1000000007
using namespace std;
typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
typedef pair<int,int> pii;
const int maxn = 1 << 12;
ll dp[500][maxn];
bool ok[12][maxn];
int n,k;
bool OK(int st,int len){
len--;
for(int i=0;i<=len/2;i++){
if(((st&(1<<i))>0)!=((st&(1<<(len-i)))>0)) return false;
}
return true;
}
ll dfs(int len,int st,int st2){
ll& ans = dp[len][st];
if(~ans) return ans;
if(len == n) return ans = 1;
ans = 0;
for(int i=0;i<=1;i++){
int newst = st<<1|i;
if(ok[k][newst]) continue;//长度为K
if(len>=k&&ok[k+1][st2<<1|i]) continue;//长度为K+1
newst=st&(~(1<<(k-1)));newst<<=1;newst|=i;
ans += dfs(len+1,newst,st<<1|i);
ans %= mod;
}
return ans;
}
void solve(){
if(k>n){
printf("%lld\n",(ll)(1<<n)%mod);
return;
}
ll ans = 0;
memset(dp, -1, sizeof(dp));
for(int i=0;i<(1<<(k-1));i++){
ans += dfs(k-1, i,0);
ans %= mod;
}
printf("%lld\n",ans);
return;
}
int main(){
//FRER();
//FREW();
for(int i=0;i<maxn;i++) for(int j=1;j<=11;j++) ok[j][i] = OK(i,j);
//cout<<ok[1][1]<<" "<<ok[1][0]<<" "<<ok[2][2]<<" "<<ok[2][3]<<endl;
go{
scanf("%d%d",&n,&k);
solve();
}
return 0;
}