题目链接:
http://codeforces.com/contest/633/problem/D
题目大意:
给一个长为n的序列,求出fn=fn-1+fn-2(满足斐波那契)成立的最长序列。
范围:
n<=1000。
思路:
可以暴力。每次任选两个数,然后相加以后看他们的和是否存在,以此类推……。
注意到0的个数其实不是那么重要(除非全部都是0),所以一般情况下只要有1个0即可。那么对于两个数都为0的情况就可以剪枝剪掉了。
代码:
#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<iostream>
#include<map>
#include<vector>
#define ll __int64
using namespace std;
int main()
{
vector<ll>vt;
vector<ll>::iterator it;
map<ll,int>mp;
ll n,i,b[1005],j,k,a[1005],f,ans,cnt,maxi,mm;
while(~scanf("%I64d",&n))
{
mm=0;
maxi=-99999999;
memset(a,0,sizeof(a));
ans=0;
mp.clear();
f=0;
ll tt=0;
k=0;
for(i=1;i<=n;i++)
{
scanf("%I64d",&a[i]);
maxi=max(maxi,a[i]);
mp[a[i]]++;
if(a[i]==0)mm++;
}
tt=n-k;
sort(a+1,a+1+n);
for(i=1;i<=n;i++)
for(j=1;j<=n;j++)
{
if(i==j)continue;
if(a[i]==0&&a[j]==0)continue;
f=0;
cnt=2;
ll xx,yy,zz;
xx=a[i];yy=a[j];
mp[xx]--;
mp[yy]--;
vt.push_back(xx);
vt.push_back(yy);
zz=xx+yy;
while(mp[zz]>0&&zz<=maxi)
{
f=1;
vt.push_back(zz);
ll t=yy;
yy=zz;
xx=t;
mp[zz]--;
zz=xx+yy;
cnt++;
}
if(cnt>ans)ans=cnt;
for(it=vt.begin();it!=vt.end();)
{
mp[*it]++; //回溯
vt.erase(it);
}
}
printf("%I64d\n",max(ans,mm));
}
}