題目鏈接:
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));
}
}