Codeforce 633D multiset

题目: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\n",maxn);
}

你可能感兴趣的:(Codeforce 633D multiset)