题目:Codeforces 633D
题意:
给出n个数,要求将这n个数排列,使得满足下列要求的前缀最小
the sequence consists of at least two elements
f0 and f1 are arbitrary
fn + 2 = fn + 1 + fn for all n ≥ 0. n<=1000
分析:
因为f0和f1是任意的,可以枚举f0和f1,然后依次往下确定f2,f3,看看f2,f3是否存在,用multiset保存原来的数,查找的效率是O(logn)所以总的时间复杂度是(n^2*logn)但是这样做会超时,中间用一个map记录一下已经出现过的f0和f1就好了。
#include<bits/stdc++.h>
using namespace std;
const int N=1e3+2;
multiset<int>ms;
multiset<int>::iterator it;
int ans;
typedef pair<int,int>pii;
map<pii,bool>mp;
void dfs(int a0,int a1)
{
it=ms.find(a0+a1);
if(it==ms.end())return;
int t=*it;
ms.erase(it);
ans++;
dfs(a1,a0+a1);
ms.insert(t);
}
int a[N];
int main()
{
int n; scanf("%d",&n);
for(int i=0;i<n;i++)scanf("%d",&a[i]),ms.insert(a[i]);
int maxn=2;
for(int i=0;i<n;i++){
for(int j=0;j<n;j++){
if(i==j)continue;
if(mp.count(pii(a[i],a[j])))continue;
mp[pii(a[i],a[j])]=1;
ans=2;
it=ms.find(a[i]);ms.erase(it);
it=ms.find(a[j]);ms.erase(it);
dfs(a[i],a[j]);
ms.insert(a[i]);ms.insert(a[j]);
if(ans>maxn)maxn=ans;
}
}
printf("%d
",maxn);
}