题意:(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); }