bzoj 3357: [Usaco2004]等差数列
f[i][j]表示i接j后面的最长长度,枚举中间的那个数用个hash表转移就行了。
水题。
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 #include<map> 6 #define N 2005 7 using namespace std; 8 int n; 9 int a[2*N]; 10 int f[2*N][2*N]; 11 int head[5000005],ver[N*2],nxt[N*2],pos[N*2],tot; 12 int st[2*N],top; 13 void add(int x,int y) 14 { 15 int aa=x%5000001; 16 st[++top]=aa; 17 tot++;nxt[tot]=head[aa];head[aa]=tot;ver[tot]=x;pos[tot]=y; 18 } 19 int now; 20 bool find(int x,int y) 21 { 22 int aa=x%5000001; 23 for(int i=head[aa];i;i=nxt[i]) 24 { 25 if(ver[i]==x) 26 { 27 pos[i]=y; 28 return 1; 29 } 30 }return 0; 31 } 32 int find(int x) 33 { 34 int aa=x%5000001; 35 for(int i=head[aa];i;i=nxt[i]) 36 { 37 if(ver[i]==x) 38 { 39 return pos[i]; 40 } 41 }return 0; 42 } 43 int main() 44 { 45 scanf("%d",&n); 46 for(int i=1;i<=n;i++) 47 { 48 scanf("%d",&a[i]); 49 } 50 int ans=2; 51 if(n==1) 52 { 53 puts("1"); 54 return 0; 55 } 56 for(int i=1;i<=n;i++) 57 { 58 for(int j=i+1;j<=n;j++) 59 { 60 f[i][j]=2; 61 } 62 } 63 for(int i=2;i<=n;i++) 64 { 65 for(int j=1;j<i;j++) 66 { 67 ans=max(ans,f[j][i]); 68 if(!find(a[j],j)) 69 { 70 //cout<<i<<' '<<a[j]<<' '<<j<<endl; 71 add(a[j],j); 72 } 73 } 74 for(int j=i+1;j<=n;j++) 75 { 76 int tmp=find(a[i]*2-a[j]); 77 if(tmp) 78 { 79 // cout<<i<<' '<<j<<endl; 80 f[i][j]=max(f[i][j],f[tmp][i]+1); 81 } 82 } 83 tot=0; 84 for(int j=1;j<=top;j++) 85 { 86 head[st[j]]=0; 87 } 88 top=0; 89 } 90 printf("%d\n",ans); 91 return 0; 92 }
#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;
}