codefroces 946F Fibonacci String Subsequences

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 }

 

posted @ 2018-03-14 11:32  Z-Y-Y-S  阅读(287)  评论(1编辑  收藏  举报