Fibonacci-ish(map去重搜尋)
阿新 • • 發佈:2018-12-11
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
- the sequence consists of at least two elements
- f(0)and f(1) are arbitrary
- f(n+2)=f(n+1)+f(n) for all n≥0.
You are given some sequence of integers a
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;
}