1. 程式人生 > >Fibonacci-ish(map去重搜尋)

Fibonacci-ish(map去重搜尋)

Problem G: Fibonacci-ish

Description

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

  1. the sequence consists of at least two elements
  2. f(0)and f(1) are arbitrary
  3. f(n+2)=f(n+1)+f(n) for all n≥0.

You are given some sequence of integers a

1,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.

Sample Input

3 1 2 -1

Sample Output

3

HINT

 In the first sample, if we rearrange elements of the sequence as -1, 2, 1, the whole sequence ai would be Fibonacci-ish.

題意:

有n個數選擇,f(0),f(1)任意取,從f(2)開始滿足f(n+2)=f(n+1)+f(n)構成斐波拉契數列,求斐波拉契數列的最大長度。

思路:

首先對陣列排序,用unique對相鄰元素去重(實際上unique並沒有刪除元素,只是把重複元素放至陣列末尾)

得到排序完全,無重複元素的陣列最大元素個數:int index=unique(a,a+n)-a;

輸入時用map統計每個數的重複次數:dis[a[i]]++;

接下來就是取起始兩個元素(任意取)

所以用兩個for迴圈即可實現

任意取得兩個數字開始(注意: 3 5 和 5 3是兩種完全不同的情況,看下這個就明白了: 3 5 8 13 ;5 3 8 11。所以兩個for迴圈均從0開始)

接下來找第三個元素以及以後的元素。

x=a[i],y=a[j].

if(dis[x+y])則說明存在x+y 這個元素,ans+1,然後重複遞迴直到找不到下一個x+y。

最終的ans取值為max(ans,dis[a[i]+a[j]]+2)(ans表示之前情況的最大值,2代表起始兩個元素,dis[a[i]+a[j]]則大有文章:代表從第三元素可以構成f(n+2)=f(n+1)+f(n)的最大長度-2)

AC程式碼:

#include<iostream>
#include<cmath>
#include<algorithm>
#include<cstring>
#include<cstdio>
#include<map>
#include<vector>
#include<stack>
#include<queue>
#include<set>
#define mod 998244353;
#define Max 0x3f3f3f3f;
#define Min 0xc0c0c0c0;
#define mst(a) memset(a,0,sizeof(a))
#define f(i,a,b) for(int i=a;i<b;i++)
using namespace std;
typedef long long ll;
const int maxn=1005;
map<int,int>dis;
int n;
int a[maxn];

int sta(int x,int y){
    int ans=0;
    if(dis[x+y]){
        dis[x+y]--;             //取值後要把該元素次數-1
        ans=sta(y,y+x)+1;
        dis[x+y]++;             //進入下一次取值前要把該元素次數重新+1
    }
    return ans;
}
int main(){
    ios::sync_with_stdio(false);
    while(cin>>n){
        dis.clear();
        for(int i=0;i<n;i++){
            cin>>a[i];
            dis[a[i]]++;
        }
        sort(a,a+n);
        int index=unique(a,a+n)-a;
        int ans=0;
        for(int i=0;i<index;i++){
            for(int j=0;j<index;j++){       //取開始兩個元素,全選擇
                if(i==j && dis[a[i]]==1){      //取到同一個元素,但該元素只有一個終止本次迴圈
                    continue;
                }
                dis[a[i]]--;                        //取值後要把該元素次數-1
                dis[a[j]]--;
                ans=max(ans,sta(a[i],a[j])+2);      //取最大的斐波拉契數列長度
                dis[a[i]]++;                        //進入下一次取值前要把該元素次數重新+1
                dis[a[j]]++;
            }
        }
        cout<<ans<<endl;
    }
    return 0;
}