Almost Arithmetical Progression(dp)
Almost Arithmetical Progression
Gena loves sequences of numbers. Recently, he has discovered a new type of sequences which he called an almost arithmetical progression. A sequence is an almost arithmetical progression, if its elements can be represented as:
- a1 = p, where p is some integer;
- ai = ai - 1 + ( - 1)i + 1·q (i > 1), where q is some integer.
Right now Gena has a piece of paper with sequence b, consisting of n integers. Help Gena, find there the longest subsequence of integers that is an almost arithmetical progression.
Sequence s1, s2, ..., sk is a subsequence of sequence b1, b2, ..., bn, if there is such increasing sequence of indexes i1, i2, ..., ik (1 ≤ i1 < i2 < ... < ik ≤ n), that bij = sj. In other words, sequence s can be obtained from b by crossing out some elements.
Input
The first line contains integer n (1 ≤ n ≤ 4000). The next line contains n integers b1, b2, ..., bn (1 ≤ bi ≤ 106).
Output
Print a single integer — the length of the required longest subsequence.
Examples
2
3 5
2
4
10 20 10 30
3
Note
In the first test the sequence actually is the suitable subsequence.
In the second test the following subsequence fits: 10, 20, 10.
题意:找一个最长的锯齿形子串 例如10 30 10 30 10
思路:%大佬%大佬%大佬 大佬tql
因为数据在1e6而n只有4000,所以大佬说可以先搞一波离散化,然后开二维dp。dp[x][y]中x表示当前数的位置,y表示x这个位置上的数字前面的数,例如1 4 1 4 dp[3][4]代表当数字为1且其前面的数字为4时的最大子串长度。dp[3][4]=dp[2][1]+1,具体看代码。
1 #include<iostream>
2 #include<cstdio>
3 #include<cstring>
4 #include<algorithm>
5 using namespace std;
6 const int maxn=4010;
7 int a[maxn],id[maxn],b[maxn];
8 int dp[maxn][maxn];
9 int n;
10 int main()
11 {
12 scanf("%d",&n);
13 for(int i=1;i<=n;i++)
14 {
15 scanf("%d",&a[i]);
16 id[i]=a[i];
17 }
18 sort(id+1,id+1+n);
19 int len=unique(id+1,id+1+n)-(id+1);
20 for(int i=1;i<=n;i++)
21 {
22 a[i]=lower_bound(id+1,id+1+n,a[i])-id;
23 }
24 int ans=0;
25 for(int i=1;i<=n;i++)
26 {
27 for(int j=1;j<i;j++)
28 {
29 dp[i][a[j]]=dp[j][a[i]]+1;
30 ans=max(ans,dp[i][a[j]]);
31 }
32 }
33 printf("%d\n",ans+1);
34 return 0;
35 }