【CF633D】Fibonacci-ish
题目描述
小y最近迷上了fibonacci数列,他定义了一种数列叫类fibonacci数列:
1.这个数列包含至少\(2\)个元素
2.\(f_0\)和\(f_1\)是任意选取的
3.\(f_{n+2}=f_{n+1}+f_n (n\geq 0)\)
现在,给出一个数列\(a_1\ldots a_n\),你可以改变数列元素的顺序,使得\(a_1\ldots a_m\)满足类fibonacci数列的条件,请求出最大的\(m\)。
\(n\leq 1000\)
题解
如果有\(0\),就先统计\(0\)的个数,然后把这些\(0\)删掉。
首先这个东西的长度是\(O(\log a_i)\)的。
暴力枚举前两个,查找是否存在第三个。
可以预处理出来。
时间复杂度:\(O(n^2\log n)\)
代码
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cstdlib>
#include<ctime>
#include<utility>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> pii;
ll a[510];
int b[510];
int n;
int c[510][510];
int d1[510];
int d2[510];
int e[510];
int main()
{
freopen("a.in","r",stdin);
freopen("a.out","w",stdout);
int i,j,k;
scanf("%d",&n);
if(n==1)
{
printf("%d\n",0);
return 0;
}
for(i=1;i<=n;i++)
scanf("%lld",&a[i]);
sort(a+1,a+n+1);
int m=0;
for(i=1;i<=n;i++)
if(i==1||a[i]!=a[i-1])
{
d1[++m]=a[i];
d2[m]=1;
}
else
d2[m]++;
for(i=1;i<=m;i++)
for(j=1;j<=m;j++)
{
k=lower_bound(d1+1,d1+m+1,d1[i]+d1[j])-d1;
if(k>m||d1[k]!=d1[i]+d1[j])
c[i][j]=0;
else
c[i][j]=k;
}
int ans=0;
for(i=1;i<=n;i++)
{
d2[i]--;
for(j=1;j<=n;j++)
if(d2[j])
{
d2[j]--;
for(k=1;k<=m;k++)
e[k]=d2[k];
ll s1=i;
ll s2=j;
int num=2;
while(c[s1][s2]&&e[c[s1][s2]])
{
e[c[s1][s2]]--;
swap(s1,s2);
s2=c[s1][s2];
num++;
}
ans=max(ans,num);
d2[j]++;
}
d2[i]++;
}
printf("%d\n",ans);
return 0;
}