Codeforces Problemset problem 633 D Fibonacci-ish —— 构造类斐波那契数列

Yash has recently learnt about the Fibonacci sequence and is very excited about it. He calls a sequence Fibonacci-ish if

the sequence consists of at least two elements
f0 and f1 are arbitrary
fn + 2 = fn + 1 + fn for all n ≥ 0.
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.

Input
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).

Output
Print the length of the longest possible Fibonacci-ish prefix of the given sequence after rearrangement.

Examples
inputCopy
3
1 2 -1
outputCopy
3
inputCopy
5
28 35 7 14 21
outputCopy
4
Note
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.

题意:

给你n个数,问你可以构造的最长类斐波那契数列是多少,什么是类斐波那契数列?f[1]和f[2]随机,f[n]=f[n-1]+f[n-2]。

题解:

这道题算是2000分中比较水的题了吧,毕竟数据范围只有1e3,那么我们暴力枚举f[1]和f[2]就好了,然后用一个map存经过的状态,那么下一次就不会以这个状态为开头,这样就不会t。

#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define pa pair<ll,ll>
const int N=1e3+5;
map<ll,int>mp;
map<pa,int>used;
int vis[N];
ll a[N];
int main()
{
    int n;
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
        scanf("%lld",&a[i]),mp[a[i]]++;
    int ans=2,cnt=0;
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=n;j++)
        {
            if(i==j||used[{a[i],a[j]}]==1)
                continue;
            used[{a[i],a[j]}]=1;
            int len=2;
            ll x=a[i],y=a[j];
            vis[++cnt]=x,vis[++cnt]=y;
            mp[x]--,mp[y]--;
            while(mp[x+y]>0)
            {
                swap(x,y);
                y+=x;
                mp[y]--;
                len++;
                vis[++cnt]=y;
                used[{x,y}]=1;
            }
            ans=max(ans,len);
            if(ans==n)
                break;
            for(int k=1;k<=cnt;k++)
                mp[vis[k]]++;
            cnt=0;
        }
        if(ans==n)
            break;
    }
    printf("%d\n",ans);
    return 0;
}

猜你喜欢

转载自blog.csdn.net/tianyizhicheng/article/details/88692636