昨天比赛的题,今天看了题解然后今天做,完全的看别人的思路,DP+hash,顺便复习了一下map与hash的区别。然后就是对自己又一次无语了,交一次发现一个bug然后就又改一次,然后wa了好多次。我想什么时候可以将这些bug全部考虑在内,然后才是真正的提高了吧!!!!
题意:给定一个整数序列。求在这个序列中存在的最长的斐波那契数列 。
解题思路:因为数据比较大,然后暴力o(n^3)肯定是要超时的,所以要改用o(n^2)的算法,即对于a[i]和a[j]在其后面寻找a[i]+a[j]的数,由此就用到hash表,采用dp[i][j]记录由a[i]和a[j]开头的数列的长度,由此求最大,下面是代码:
#include<iostream>
#include<cstdio>
#include<string>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<queue>
#include<stack>
#include<vector>
#include<climits>
#include<map>
#include<utility>
#include<ext/hash_map>
using namespace std;
using __gnu_cxx::hash_map;
#define rep(i,n) for(int i=0; i<(n); ++i)
#define repf(i,n,m) for(int i=(n); i<=(m); ++i)
#define repd(i,n,m) for(int i=(n); i>=(m); --i)
#define ll long long
#define inf 1000000000
#define exp 0.000000001
#define N 3010
int a[N];
short dp[N][N];
int n;
//hash_map <int,int>mp;
hash_map<int,int>mp;
hash_map<int,int>::iterator it;
int main()
{
int test=0;
while(scanf("%d",&n)!=EOF)
{
if(test!=0) printf("\n");
test++;
repf(i,1,n) scanf("%d",&a[i]);
repf(i,1,n)
repf(j,i+1,n)
dp[i][j]=1;
mp.clear();
int m=0,x,y;
x=a[1];
repd(i,n,1)
{
repf(j,1,i-1)
{
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;
}
// printf("%d\n",m+1);
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;
}
// printf("%d\n",m+1);
if(m==0)
{
printf("2\n");
printf("%d %d\n",a[1],a[2]);
continue;}
printf("%d\n",m+1);
x=a[x],y=a[y];
printf("%d",x);
repf(i,1,m)
{
printf(" %d",y);
int z=x+y; x=y;y=z;
}
printf("\n");
}
return 0;
}