Solution
- d p [ i ] [ j ] : 以 a [ i ] , a [ j ] 结 尾 的 等 差 数 列 的 最 大 长 度 dp[i][j]:以a[i], a[j]结尾的等差数列的最大长度 dp[i][j]:以a[i],a[j]结尾的等差数列的最大长度
- 利用
a
[
i
]
∗
2
=
a
[
l
]
+
a
[
r
]
a[i] * 2 = a[l] + a[r]
a[i]∗2=a[l]+a[r] 的性质进行状态的转移
d p [ i ] [ r ] = m a x ( d p [ i ] [ r ] , d p [ l ] [ i ] + 1 ) l < i < r dp[i][r] = max(dp[i][r], dp[l][i] + 1) \\l < i < r dp[i][r]=max(dp[i][r],dp[l][i]+1)l<i<r
当然a数组是排序后的有序数组,所以可以利用双指针进行状态之间的转移。
时间复杂度O(n)
Code
#define ll long long int
const int N = 5e3 + 3, M = 5e6 + 6;
int f[N][N];
ll a[N];
int main()
{
int n; cin >> n;
for (int i = 1; i <= n; i++)
cin >> a[i];
sort(a + 1, a + n + 1);
for (int i = 1; i <= n; i++)
for (int j = i + 1; j <= n; j++)
f[i][j] = 2;
int ans = 0;
for (int i = 1; i <= n; i++)
{
int l = i - 1, r = i + 1;
while (l >= 1 && r <= n)
if (a[i] * 2 == a[l] + a[r])
{
f[i][r] = max(f[i][r], f[l][i] + 1);
ans = max(ans, f[i][r]);
l--;//r++,二者取一,但不可都写
}
else if (a[i] * 2 > a[l] + a[r]) r++;
else l--;
}
cout << ans << endl;
return 0;
}
求助 =_=
有大佬可以讲讲,为什么当a[i] * 2 == a[l] + a[r]
时,两个指针不能同时移动?
但是,无论是移动右边还是左边,结果都正确。