【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;
}
posted @ 2018-03-05 21:10  ywwyww  阅读(200)  评论(0编辑  收藏  举报