题面
小y最近迷上了fibonacci数列,他定义了一种数列叫fibonacccccci数列:
1、这个数列包含至少2个元素;
2、f[0]和f[1]是任意选取的;
3、f[n+2]=f[n+1]+f[n] (n>=0);
现在,给出一个数列a[1..n],你可以改变数列元素的顺序,使得a[1..m]满足fibonacccccci数列的条件,请求出最大的m。
【数据范围】
对于20%的数据满足:n<=7;
对于100%的数据满足:n<=500,0<=|a[i]|<=10^9。
分析
数据范围显然是搞笑,所以就随便乱搞,先开始准备来个三四次方的打个暴力,然后优化了一下就懒得分段了..
暴力枚举选哪两个点做f[0]和f[1](为方便计数,代码里写的f[1]和f[2])
其实就一个优化,就是先排序,然后每次查找算出来的函数值是否存在的时候二分一下就好,还有注意判断0的情况
代码
#include<bits/stdc++.h> using namespace std; #define N 550 #define ll long long ll a[N],f[N],vis[N]; ll n,l,r,mid,ans,num,pos,cnt,zero,flag; inline void read(ll &x) { ll f=1;x=0;char ch=getchar(); while(ch>'9'||ch<'0'){if(ch=='-')f=-1;ch=getchar();} while(ch<='9'&&ch>='0'){x=x*10+ch-'0';ch=getchar();} x*=f; } void solve() { for(ll i=1;i<=n;i++) { if(n-i+1<ans)break; for(ll j=i+1;j<=n;j++) { ++cnt; if(n-i+2<ans)break; f[1]=a[i];f[2]=a[j]; if(n<3) num=n; else num=3; vis[i]=vis[j]=cnt; while(num<n) { f[num]=f[num-1]+f[num-2];flag=0; pos=lower_bound(a+1,a+1+n,f[num])-a; for(ll k=pos-2;k<=pos+2;k++) if(f[num]==a[k]&&vis[k]!=cnt) { flag=1;vis[k]=cnt; break; } if(!flag){num--;break;} num++; flag=0; if(num==n) if(f[num-1]+f[num-2]!=a[n]||vis[n]==cnt) { num--; break;} } ans=max(ans,num); } } printf("%lld ",ans); } int main() { read(n); for(ll i=1;i<=n;i++) read(a[i]); sort(a+1,a+1+n); for(int i=1;i<=n;i++) if(!a[i]) zero++; ans=zero; solve(); return 0; }