Fibonacci(dp)

描述

Given a sequence {an}, how many non-empty sub-sequence of it is a prefix of fibonacci sequence.

A sub-sequence is a sequence that can be derived from another sequence by deleting some elements without changing the order of the remaining elements.

The fibonacci sequence is defined as below:

F1 = 1, F2 = 1

Fn = Fn-1 + Fn-2, n>=3

输入

One line with an integer n.

Second line with n integers, indicating the sequence {an}.

For 30% of the data, n<=10.

For 60% of the data, n<=1000.

For 100% of the data, n<=1000000, 0<=ai<=100000.

输出

One line with an integer, indicating the answer modulo 1,000,000,007.

样例提示

The 7 sub-sequences are:

{a2}

{a3}

{a2, a3}

{a2, a3, a4}

{a2, a3, a5}

{a2, a3, a4, a6}

{a2, a3, a5, a6}


样例输入
6
2 1 1 2 2 3
样例输出
7
      首先可以枚举出所有小于 100000的斐波那契数,并且把他们的位置标记一下(pos数组)。把所给的数列筛一遍(a[]),只留下属于斐波那契数的。然后就可以进行dp操作,定义count[n]为以第n个斐波那契数结尾的结果。我们遍历a[],如果a[n]不为1,count[n]+=count[n-1];如果a[n]为1,我们要进行讨论,可以这样操作
if(a[i]==1)
			{
				num1++;// //num1代表当前有多少个1
			 	count[2]=num1*(num1-1)/2;/*因为斐波那契数列前两个数都为1,所以以第二个斐波那契数结尾的结果就是
                                           num1*(num1-1)/2;*/
				count[2]%=1000000007;
				count[1]=num1;//所以以第一个斐波那契数结尾的结果就是num1
			}
最后把所有count[1]加到count[k]取模就是最后答案。k的话估计下就好了。不会很大。
#include<iostream>
using namespace std;
int f[1000005];
int num[1000005];
int a[1000005];
int pos[1000005];
long long count[1000005];
int main()
{
	f[1]=1;
	f[2]=1;
	pos[1]=1;
	pos[2]=2;
	for(int i=3;f[i-1]<1000005;i++)
	{
		f[i]=f[i-1]+f[i-2];
		pos[f[i]]=i;
	}
	//cout<<f[4]<<endl;
	int n;
	while(~scanf("%d",&n))
	{
		//memset(pos,0,sizeof(pos));
		int nn=0;
		for(int i=1;i<=n;i++)
	    {
		   scanf("%d",&num[i]);
		   if(pos[num[i]]!=0)
		  {
			a[++nn]=num[i];
		  }
	    }
		//cout<<nn<<endl;
		long long num1=0;
		for(int i=1;i<=nn;i++)
		{
			if(a[i]==1)
			{
				num1++;// //num1代表当前有多少个1
			 	count[2]=num1*(num1-1)/2;/*因为斐波那契数列前两个数都为1,所以以第二个斐波那契数结尾的结果就是
                                           num1*(num1-1)/2;*/
				count[2]%=1000000007;
				count[1]=num1;//所以以第一个斐波那契数结尾的结果就是num1
			}
			else
			{
				count[pos[a[i]]]+=count[pos[a[i]]-1];
				count[pos[a[i]]]%=1000000007;
			}
		}
		long long ans=0;
		for(int i=1;i<50;i++)
		{
			ans+=count[i];
			ans%= 1000000007;
		}
		printf("%lld\n",ans);
	}
	

}












  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值