zoj 2672 Fibonacci Subsequence(hash + dp)

来源:互联网 发布:虚拟软件下载 编辑:程序博客网 时间:2024/05/23 01:14

题目:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=1672

Fibonacci Subsequence

Time Limit: 5 Seconds      Memory Limit: 32768 KB      Special Judge

A sequence of integer numbers a1 , a2 , ..., an is called a Fibonacci sequence if ai = ai-2+ai-1 for all i=3,4,...,n.

Given a sequence of integer numbers c1 , c2 , ..., cm you have to find its longest Fibonacci subsequence.

Input

There are several test cases in the input. The first line of each case contains m (1 <= m <= 3,000). Next line contains m integer numbers not exceeding 109 by their absolute value.
There is a new line between each case.

Output

On the first line of each case print the maximal length of the Fibonacci subsequence of the given sequence. On the second line print the subsequence itself.
There is a new line between each case.

Example

InputOutput
101 1 3 -1 2 0 5 -1 -1 8
51 -1 0 -1 -1

寻找的大致思路:前面选择两个数字,两者的和是我们要找的目标,在后面寻找,能找到就增加长度。这样下来,时间复杂度是O(n^3),对于m<=3000来讲是不行的。C++ 中的hash_map是个好东西,查找效率是常数级别,基础是哈希表,以空间换时间,map也能构造映射关系查找,查找效率是O(logn),基础是rb_tree红黑树。在大多数情况下哈希的效率更高。但某些情况不如map。由多个个体构造极值情况:DP。因为已经用了hash,所以DP数组可以用short int。short int 的取值范围是-32768----32767。不然会MLE。
#include <cstdio>#include <cstring>#include <iostream>#include <hash_map>using namespace std;using __gnu_cxx::hash_map;const int maxn=3010;hash_map<int,int> mymap;hash_map<int ,int >::iterator ix;void show(){    for(ix=mymap.begin();ix!=mymap.end();ix++){         cout<<ix->first<<" "<<ix->second<<"    ";    }    cout<<endl;}int a[maxn];//int dp[maxn][maxn];short dp[maxn][maxn];int main(){    //freopen("cin.txt","r",stdin);    int n;    bool first=1;    while(cin>>n){        if(!first)puts("");        first=0;        for(int i=1;i<=n;i++){            scanf("%d",&a[i]);        }        for(int i=1;i<=n;i++){            for(int j=i+1;j<=n;j++)dp[i][j]=1;        }        mymap.clear();        int top=0,low=a[1],high;        for(int i=n;i>=1;i--){            for(int j=1;j<i;j++){                int k=a[i]+a[j];                ix=mymap.find(k);                if(ix!=mymap.end()){                    dp[j][i]=dp[i][ix->second]+1;   // 小下标 --- 大下标                    if(dp[j][i]>top){                        top=dp[j][i];                        low=j;                        high=i;                    }                }            }            mymap[a[i]]=i;        }        if(n==1){  printf("1\n%d\n",a[1]); continue; }        if(n==2) {   printf("2\n%d %d\n",a[1],a[2]);  continue; }        if(top==0){   printf("2\n%d %d\n",a[1],a[2]); continue; }        printf("%d\n",top+1);        printf("%d",a[low]);        int q1=a[low],q2=a[high];        for(int i=0;i<top;i++){  // when top=4  sum of numbers is 5            printf(" %d",q2);            int t=q1;            q1=q2;            q2=t+q2;        }        puts("");    }    return 0;}
又犯了逻辑错误,主函数的结果处理如果是这样是WA的:
        if(n==1){  printf("1\n%d\n",a[1]); }        else if(n==2) {   printf("2\n%d %d\n",a[1],a[2]);  continue; }        if(top==0){   printf("2\n%d %d\n",a[1],a[2]);  }        else {            printf("%d\n",top+1);            printf("%d",a[low]);            int q1=a[low],q2=a[high];            for(int i=0;i<top;i++){  // when top=4  sum of numbers is 5                printf(" %d",q2);                int t=q1;                q1=q2;                q2=t+q2;            }            puts("");        }




0 0
原创粉丝点击