zoj 2672 DP+hash

来源:互联网 发布:10.11.4制作mac安装u盘 编辑:程序博客网 时间:2024/05/22 14:47

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

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

题目大意:求出给定序列中最长的一组子序列:a[i]+a[i+1]=a[i+2],满足Fibonacci关系。

解题思路:

               其实这是一道dp的题目,本来我们假设dp[i][j] 代表的是以a[i]和a[j]为开头的序列的长度。i从1~n而j从1~i-1,遍历,每对ij都作为相加看是否在已遍历过的i~n里有没有二者的和,如果有找出这个数的位置x,dp[j][i]=dp[i][x]+1.这样一来思路就清晰了。但是这里还有一个问题,我们整个问题下来是O(n^3)的复杂度,显然这对n==3000的数据量来说是无法接受的。因此我们在寻找a[i]+a[j]的时候运用哈希表复杂度为O(1),这样一来复杂度就降到的O(n^2), 就可以通过了。

附上hash_map的应用:http://blog.sina.com.cn/s/blog_4ac0a0d30100ukpp.html

#include <stdio.h>#include <string.h>#include <iostream>#include <hash_map>using namespace std;using __gnu_cxx::hash_map;#define N 3010int a[N];int dp[N][N];int n;hash_map<int,int>mp;hash_map<int ,int >::iterator it;int main(){    int test=0;    while(~scanf("%d",&n))    {        if(test!=0)            printf("\n");        test++;        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;        mp.clear();        int m=0,x,y;        x=a[1];        for(int i=n;i>=1;i--)        {            for(int j=1;j<i;j++)            {                int k=a[i]+a[j];                it=mp.find(k);                if(it!=mp.end())                {                    dp[j][i]=dp[i][it->second]+1;                    if(dp[j][i]>m)                    {                        m=dp[j][i];                        x=j;                        y=i;                    }                }            }            mp[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(m==0)        {            printf("2\n%d %d\n",a[1],a[2]);        }        else        {            printf("%d\n",m+1);            x=a[x],y=a[y];            printf("%d",x);            for(int i=1;i<=m;i++)            {                printf(" %d",y);                int z=x+y;                x=y;                y=z;            }            printf("\n");        }    }    return 0;}/*const int maxn=1000010;const int maxd=15;const int seed=30007;struct HASHMAP{    int head[seed],next[maxn],size;    LL state[maxn];    LL f[maxn];    void clear(){        size=0;        memset(head,-1,sizeof(head));    }    void insert(LL st,LL ans){        int h=st%seed;        for (int i=head[h];i!=-1;i=next[i]){            if (state[i]==st)            {                f[i]=max(f[i],ans);                return;            }        }        state[size]=st;        f[size]=ans;        next[size]=head[h];        head[h]=size++;    }}hm[2];



0 0