Yash has recently learnt about the Fibonacci sequence and is very excited about it. He calls a sequence Fibonacci-ish if
You are given some sequence of integers a1, a2, ..., an. Your task is rearrange elements of this sequence in such a way that its longest possible prefix is Fibonacci-ish sequence.
The first line of the input contains a single integer n (2 ≤ n ≤ 1000) — the length of the sequence ai.
The second line contains n integers a1, a2, ..., an (|ai| ≤ 109).
Print the length of the longest possible Fibonacci-ish prefix of the given sequence after rearrangement.
3 1 2 -1
3
5 28 35 7 14 21
4
In the first sample, if we rearrange elements of the sequence as - 1, 2, 1, the whole sequence ai would be Fibonacci-ish.
In the second sample, the optimal way to rearrange elements is ,
,
,
, 28.
#include<stdio.h> #include<iostream> #include<string.h> #include<string> #include<ctype.h> #include<math.h> #include<set> #include<map> #include<vector> #include<queue> #include<bitset> #include<algorithm> #include<time.h> using namespace std; void fre() { freopen("c://test//input.in", "r", stdin); freopen("c://test//output.out", "w", stdout); } #define MS(x,y) memset(x,y,sizeof(x)) #define MC(x,y) memcpy(x,y,sizeof(x)) #define MP(x,y) make_pair(x,y) #define ls o<<1 #define rs o<<1|1 typedef long long LL; typedef unsigned long long UL; typedef unsigned int UI; template <class T1, class T2>inline void gmax(T1 &a, T2 b) { if (b>a)a = b; } template <class T1, class T2>inline void gmin(T1 &a, T2 b) { if (b<a)a = b; } const int N = 1010, M = 0, Z = 1e9 + 7, ms63 = 0x3f3f3f3f; int n; int a[N]; int ans; map<int,int>mop; LL f[N]; void go(int x, int y) { //if (x == 0 && y == 0){gmax(ans, mop[0]);return;} --mop[x]; --mop[y]; f[1] = x; f[2] = y; int i; for (i = 3;; ++i) { f[i] = f[i - 1] + f[i - 2]; if (mop.find(f[i]) != mop.end() && mop[f[i]])--mop[f[i]]; else break; } gmax(ans, i - 1); for (int j = 1; j < i; ++j)++mop[f[j]]; } pair<int, int>b[N*N]; int main() { while (~scanf("%d", &n)) { mop.clear(); for (int i = 1; i <= n; ++i)scanf("%d", &a[i]), ++mop[a[i]]; int m = 0; for (int i = 1; i <= n; ++i) { for (int j = 1; j <= n; ++j)if(j!=i) { b[++m] = MP(a[i], a[j]); } } b[0].first = 2e9; sort(b + 1, b + m + 1); ans = 0; for (int i = 1; i <= m; ++i) { if (b[i].first != b[i - 1].first || b[i].second != b[i - 1].second) { go(b[i]. first, b[i].second); } } printf("%d\n", ans); } return 0; } /* 【trick&&吐槽】 1,这道题在一个傻叉错误上栽了3次跟头。 就是因为我读错题了, 把 arbitrary 当做是"不相同的"的意思,而这实际是"任意的"的意思。 知道后来才发现。= = 2,不要忘了枚举开头的时候,要判定i!=j >_< 囧 【题意】 有n(2<=n<=1000)个数,每个数的权值都在[-1e9,1e9]范围内。 我们要把它们按照一定方式排列。 使得最前几位是斐波那契数列,且长度尽可能长 问你这最长的斐波那契数列的长度是多少 【类型】 暴力枚举 【分析】 首先,我们发现,只要我们枚举了前2位,后面的所有位自然也可以算出来了。 如果我们用mop[]存一个数字的数量,那么,我们就可以验证这2位作为开头的可行性。 然而,这个复杂度看似是O(n^3 log(n) )的。 不过,给定的数字都是-1e9~1e9范围的数, 于是,如果开头2个数都是整数或者负数,我们的斐波那契项数最多不过30 如果是1正1负作为开头的话,且和为正,继续向下迭代的话,我们发现也是向小缩小, 而且为了保证正负交替,依然需要|abs(fib[i])|>=2|abs(fib[i+1])|。 于是不过30次就变成0。 而只有0 0作为开头,答案才会被延长到超过60项。 我们可以把所有开头pair做去重,或者特判0 0,都可以顺利AC这道题。 【时间复杂度&&优化】 O(n^2 * 30 * log(n)) 【数据】 有一组数据 -1 1 -2 2 -3 3 -4 4 -5 5 -6 6 ... 0 0 0 0 0... 对于这组数据,我们其实只有1000个长达1000(≈)个数列,也不会TLE啦 不过特判还是没有把询问去重快哦 */