CF 633D斐波那契

Posted pedestrian6

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了CF 633D斐波那契相关的知识,希望对你有一定的参考价值。

狂WA巨坑题

题意:给出n<=1000个数,能组成的类似斐波那契的数列最长长度是多少(fn=fn-1+fn-2,n>=2)

solution:看起来是一道相当高端的数论题,还是D题?我现在都没现场切过D 没想到做法就是暴力?不过暴力可证复杂度OK

感觉枚举一下前两项,一直往下找,这样用个map维护一下复杂度也是n^3logn啊

不过打个斐波那契数列的表就能发现,因为每个值范围[-1e9,1e9],所以即使数列第一个和第二个是绝对值很小的两个1也会在45项左右停止,这样的话就算50项,复杂度好像可以,不过坑点巨多

坑点1:要把0特殊拿出来,因为如果前两项是0整个数列就全都是0,绝对值不上升,毒瘤数据稳稳卡成n^3logn

坑点2:如果有0要放进去1个,因为可能会有 0,x,x,……或x,0,x……这种操作

坑点3:元素有重啊!答案数列也可能有重,所以map不能存bool要存int

坑点4:map映射元素的个数,所以在原始数组中枚举前两项要去重。如果不去重,极端情况下所有数45个一组正好一个斐波那契数列,然后重复20遍,这样n^2*45,但是不要忘了还有map logn大约是10可能会被卡(99点果然被卡)

坑点5:去完重后,注意数列前两个可以相同,前提是该数出现次数>1

有些神奇刚才unique之前没sort(不能完全去重)竟然过了。。。

 

技术分享图片
 1 #include<iostream>
 2 #include<cstdio>
 3 #include<map>
 4 #include<algorithm>
 5 using namespace std;
 6 map <int,int> M,T;//int开始写成bool了 
 7 int n,A[2020],ans;
 8 int main(){
 9     scanf("%d",&n);
10     int i,j;
11     for (i=1;i<=n;i++){
12         scanf("%d",&A[i]);
13         if (!A[i]) i--,n--,ans++;
14         else M[A[i]]++;
15     }
16     if (ans) n++,M[0]=1;//有0的话给去掉0的数列加个0 
17     sort(A+1,A+n+1);//忘了 
18     n=unique(A+1,A+n+1)-A-1;//去重提高效率 
19     for (i=1;i<=n;i++) 
20     for (i=1;i<=n;i++) for (j=1;j<=n;j++)
21       if (i==j&&M[A[i]]<2) continue;
22       //不能直接i=j就退出因为数列前两个可能一样 
23       else{
24         int cur,a1=A[i],a2=A[j],sum=2;
25         T.clear();
26         T[a1]++; T[a2]++;
27         while (1){
28             cur=a1+a2; 
29             if (T[cur]==M[cur]) break;
30             T[cur]++; a1=a2; a2=cur; sum++;
31         }
32         ans=max(ans,sum);
33     }
34     cout<<ans;
35 }
技术分享图片

以上是关于CF 633D斐波那契的主要内容,如果未能解决你的问题,请参考以下文章

CF446CDZY Loves Fibonacci Numbers (线段树 + 斐波那契数列)

类似斐波那契数列的递归

CF717A Festival Organization(第一类斯特林数,斐波那契数列)

CF735C 数论平衡树叶子节点的最大深度贪心斐波那契条件归一化

08《算法入门教程》递归算法之斐波那契数列

谁能帮我用JAVA编写一个斐波那契数列,用eclipse实现,代码不对不采纳!