Codeforce 633D multiset

来源:互联网 发布:蓝月翅膀升阶数据 编辑:程序博客网 时间:2024/06/06 00:51

题目:http://codeforces.com/contest/633/problem/D
题意:
给出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);}
0 0
原创粉丝点击