dp[p][x][y]表示s串的[x, y]部分在F(p)的所有子串中出现多少次
那么有dp[p][i][j] = ∑(dp[p-1][i][k]*dp[p-2][k+1][j], i≤k<j)+dp[p-1][i][j]+dp[p-2][i][j]
其中当i=1或者j=n时
dp[p][i][j] += (2^len(p-1)-1)*dp[p-2][i][j] 或者 (2^len(p-2)-1)*dp[p-1][i][j]
#include<stdio.h>
#define mod 1000000007
#define LL long long
char str[105];
LL dp[105][105][105], F[105] = {1,1};
LL Pow(LL x, LL y)
{
LL ans = 1;
while(y)
{
if(y%2)
ans = ans*x%mod;
x = x*x%mod;
y /= 2;
}
return ans;
}
int main(void)
{
int n, m, i, j, k, p, len;
scanf("%d%d%s", &n, &m, str+1);
for(i=1;i<=n;i++)
{
if(str[i]=='1')
dp[1][i][i] = 1;
else
dp[0][i][i] = 1;
}
for(i=2;i<=m;i++)
F[i] = (F[i-1]+F[i-2])%(mod-1);
for(p=2;p<=m;p++)
{
for(len=1;len<=n;len++)
{
for(i=1;i+len-1<=n;i++)
{
j = i+len-1;
dp[p][i][j] = (dp[p-1][i][j]+dp[p-2][i][j])%mod;
for(k=i;k<=j-1;k++)
dp[p][i][j] = (dp[p][i][j]+dp[p-1][i][k]*dp[p-2][k+1][j])%mod;
if(i==1)
dp[p][i][j] = (dp[p][i][j]+(Pow(2, F[p-1])-1)*dp[p-2][i][j])%mod;
if(j==n)
dp[p][i][j] = (dp[p][i][j]+dp[p-1][i][j]*(Pow(2, F[p-2])-1))%mod;
}
}
}
printf("%lld\n", dp[m][1][n]);
return 0;
}