首页 > 代码库 > bzoj 3357: [Usaco2004]等差数列

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;
}

bzoj 3357: [Usaco2004]等差数列