Description
定义$F(x)$为$F(x−1)$与$F(x−2)$的连接(其中$F(0)="0"$,$F(1)="1"$)给出一个长度为$n$的$01$字符串$s$,询问$s$在$F(x)$
的所有子序列中出现了多少次。
$1≤n≤100$
$0≤x≤100$
Examples
Input
2 4
11
Output
14
Input
10 100
1010101010
Output
553403224
$f[i][l][r]$表示有多少$F[i]$的子序列里包含字符串[l,r]
有3种情况:
1.$l~r$都在$F[i-1]$中
2.$l~r$都在$F[i-2]$中
3.$l~k$在$F[i-1]$中,$k+1~r$都在$F[i-2]$中
对于第1种情况,如果$r=n$,那么$F[i-2]$就可以随便选
第二种情况也一样
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<cmath> 5 #include<algorithm> 6 using namespace std; 7 int Mod=1e9+7; 8 int f[101][101][101],len[101],n,m; 9 char s[101]; 10 int qpow(int x,int y) 11 { 12 int res=1; 13 while (y) 14 { 15 if (y&1) res=1ll*res*x%Mod; 16 x=1ll*x*x%Mod; 17 y>>=1; 18 } 19 return res; 20 } 21 int dfs(int x,int l,int r) 22 {int k; 23 if (f[x][l][r]!=-1) return f[x][l][r]; 24 if (x==1||x==0) 25 { 26 if (l==r&&s[l]==(char)(x+‘0‘)) return 1; 27 return 0; 28 } 29 int cnt=0; 30 cnt+=1ll*dfs(x-1,l,r)*((r==n)?qpow(2,len[x-2]):1)%Mod;cnt%=Mod; 31 cnt+=1ll*dfs(x-2,l,r)*((l==1)?qpow(2,len[x-1]):1)%Mod;cnt%=Mod; 32 for (k=l;k<r;k++) 33 { 34 cnt+=1ll*dfs(x-1,l,k)*dfs(x-2,k+1,r)%Mod; 35 cnt%=Mod; 36 } 37 return f[x][l][r]=cnt; 38 } 39 int main() 40 {int i; 41 cin>>n>>m; 42 memset(f,-1,sizeof(f)); 43 len[1]=1;len[0]=1; 44 for (i=2;i<=m;i++) 45 len[i]=(len[i-1]+len[i-2])%(Mod-1); 46 cin>>s+1; 47 printf("%d\n",dfs(m,1,n)); 48 }