Fibonacci前缀子串个数

题意:(http://hihocoder.com/problemset/problem/1239)给定一个序列,问该序列中蕴含的fibonacci前缀子序列有多少个。如长度为4的序列1122,答案为5,分别为1、1、11、112、112。题目保证输入中的每个数不大于100000.

思路:先构造不大于100000的fibonacci序列,并且将数字之于下标hash一下。dp[i]表示第i个fibonacci数为最后一个数的子序列个数。然后从左往右扫一遍输入串,如果该数不是fibonacci数,那么不管。如果是1,特判;如果是其他的fibonacci数,那么答案加上前一个fibonacci数为终止数的子序列个数(通过hash),并且更新当前的dp。如果解释的不清楚,见代码:

#include <cstdio>
#include <cstring>
#include <cstdlib>
#define M 100000
#define N 1000000
int s[N],f[M],hash[M+5];
int t[M];
int n;
void init(){
    memset(t, 0, sizeof(t));
    memset(hash,0,sizeof(hash));
    f[0] = f[1] = 1;
    for(int i = 2;;i++){
        f[i] = f[i-1]+f[i-2];
        if(f[i] > M)
            break;
        hash[f[i]] = i;
    }
}
int main(){
    init();
    scanf("%d",&n);
    for(int i = 0;i<n;i++)
        scanf("%d",&s[i]);
    int res = 0;
    for(int i = 0;i<n;i++){
        if(s[i] == 1){
            res += t[0]+1;
            t[1] += t[0];
            t[0]++;
            t[1] %= 1000000007;
        }else if(hash[s[i]]){
            int tmp = hash[s[i]];
            res += t[tmp-1];
            t[tmp] += t[tmp-1];
            t[tmp] %= 1000000007;
        }
        res %= 1000000007;
    }
    printf("%d\n",res);
}


你可能感兴趣的:(Fibonacci前缀子串个数)