您的位置:首页 > 其它

bzoj 3357: [Usaco2004]等差数列

2017-02-15 11:21 246 查看
  f[i][j]表示i接j后面的最长长度,枚举中间的那个数用个hash表转移就行了。

  水题。

  

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<map>
#define N 2005
using namespace std;
int n;
int a[2*N];
int f[2*N][2*N];
int head[5000005],ver[N*2],nxt[N*2],pos[N*2],tot;
int st[2*N],top;
void add(int x,int y)
{
int aa=x%5000001;
st[++top]=aa;
tot++;nxt[tot]=head[aa];head[aa]=tot;ver[tot]=x;pos[tot]=y;
}
int now;
bool find(int x,int y)
{
int aa=x%5000001;
for(int i=head[aa];i;i=nxt[i])
{
if(ver[i]==x)
{
pos[i]=y;
return 1;
}
}return 0;
}
int find(int x)
{
int aa=x%5000001;
for(int i=head[aa];i;i=nxt[i])
{
if(ver[i]==x)
{
return pos[i];
}
}return 0;
}
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
scanf("%d",&a[i]);
}
int ans=2;
if(n==1)
{
puts("1");
return 0;
}
for(int i=1;i<=n;i++)
{
for(int j=i+1;j<=n;j++)
{
f[i][j]=2;
}
}
for(int i=2;i<=n;i++)
{
for(int j=1;j<i;j++)
{
ans=max(ans,f[j][i]);
if(!find(a[j],j))
{
//cout<<i<<' '<<a[j]<<' '<<j<<endl;
add(a[j],j);
}
}
for(int j=i+1;j<=n;j++)
{
int tmp=find(a[i]*2-a[j]);
if(tmp)
{
//  cout<<i<<' '<<j<<endl;
f[i][j]=max(f[i][j],f[tmp][i]+1);
}
}
tot=0;
for(int j=1;j<=top;j++)
{
head[st[j]]=0;
}
top=0;
}
printf("%d\n",ans);
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: