题目链接:
题意:
给定一个长度为n的序列然后判断这个序列有多少个子序列是Fibonacci数列的前缀。
分析:
简单的dp,因为a[i]<100000,因此Fibonacci数列最多有30项。设
dp[i][j]
表示到第i个数为止含有Fibonacci数列的前缀长度为j的有多少种。
转移分为两种:
a[i]=1 :
- dp[i][0]=d[i−1][0]+1,dp[i][1]=dp[i−1][1]+dp[i−1][0];
a[i]≠1anda[i]=Fibonacci[j] :
- dp[i][j]=dp[i−1][j]+dp[i−1][j−1];
Code
#include <bits/stdc++.h>
using namespace std;
const int maxn = 1e6+10;
typedef long long LL;
const LL mod = 1e9+7;
LL dp[maxn][30];
int a[maxn];
int fib[30];
void init(){
fib[0]=1;
fib[1]=1;
for(int i=2;i<30;i++){
fib[i]=fib[i-1]+fib[i-2];
}
}
int main()
{
init();
int n;
while(~scanf("%d",&n)){
for(int i=1;i<=n;i++)
scanf("%d",a+i);
for(int i=0;i<30;i++)
dp[0][i]=0;
for(int i=1;i<=n;i++){
for(int j=0;j<30;j++)
dp[i][j]=dp[i-1][j];
int pos = lower_bound(fib,fib+30,a[i])-fib;
if(fib[pos]==a[i]){
if(fib[pos]==1){
dp[i][pos+1]=(dp[i][pos+1]+dp[i-1][0])%mod;
dp[i][pos]=(dp[i][pos]+1)%mod;
}
else{
dp[i][pos]=(dp[i][pos]+dp[i-1][pos-1])%mod;
}
}
}
LL ans = 0;
for(int i=0;i<26;i++){
ans = (ans+dp[n][i])%mod;
}
printf("%lld\n",ans);
}
return 0;
}