#843. 等差数列

题目链接

#843. 等差数列

题目描述

给定一个大小为n的集合{S}, 你可以从中挑选若干个数组成等差数列, 求最长的等差数列长度

输入描述

一行一个整数n5000

接下来一行n个整数|Si|<231, 描述集合{S}中的元素

输出描述

一行一个整数, 描述最长的等差数列的长度

样例输入

10 14 1 3 5 6 8 9 10 12 13

样例输出

5

样例解释

等差数列包括(仅包括两项的不列举) 1 3 5 1 5 9 13 3 6 9 12 3 8 13 5 9 13 6 8 10 12 14 其中6 8 10 12 14最长,长度为5。

解题思路

dp

  • 状态表示:f[i][j] 表示后等差数列后两项为 a[j]a[i] 时的最长长度

二分

  • 状态计算:此时,计算公差 d=a[i]a[j]

    • 如果前面存在 a[pos]=a[j]d ,则 f[i][j]=f[j][pos]+1
    • 否则,f[i][j]=2
  • 时间复杂度:O(n2logn)

双指针

设置等差数列的三项 aL,ai,aR,则有 aRai=aiaL,枚举中间的 iLR 分别为左右指针,当存在 aRai=aiaL 时转移状态 f[i][R]=max(f[i][R],f[L][i]+1),其中 f[L][i] 是已知的,因为 i 从小到大枚举且 L<i,然后移动左右指针任意一个,当 aRai>aiaLaiaL 的公差偏小,L,反之,R++

  • 时间复杂度:O(n2)

代码

  • 二分
// %%%Skyqwq #include <bits/stdc++.h> //#define int long long #define help {cin.tie(NULL); cout.tie(NULL);} #define pb push_back #define fi first #define se second #define mkp make_pair using namespace std; typedef long long LL; typedef pair<int, int> PII; typedef pair<LL, LL> PLL; template <typename T> bool chkMax(T &x, T y) { return (y > x) ? x = y, 1 : 0; } template <typename T> bool chkMin(T &x, T y) { return (y < x) ? x = y, 1 : 0; } template <typename T> void inline read(T &x) { int f = 1; x = 0; char s = getchar(); while (s < '0' || s > '9') { if (s == '-') f = -1; s = getchar(); } while (s <= '9' && s >= '0') x = x * 10 + (s ^ 48), s = getchar(); x *= f; } const int N=5005; int n,a[N]; int f[N][N]; int main() { read(n); for(int i=1;i<=n;i++)read(a[i]); sort(a+1,a+1+n); int res=n>=2?2:1; for(int i=1;i<=n;i++) for(int j=1;j<i;j++) { int d=a[i]-a[j]; int pos=upper_bound(a+1,a+1+n,a[j]-d)-a-1; if(pos>=1&&pos<=n&&a[pos]==a[j]-d) { f[i][j]=f[j][pos]+1; res=max(res,f[i][j]); } else f[i][j]=2; } printf("%d",res); return 0; }
  • 双指针
// %%%Skyqwq #include <bits/stdc++.h> //#define int long long #define help {cin.tie(NULL); cout.tie(NULL);} #define pb push_back #define fi first #define se second #define mkp make_pair using namespace std; typedef long long LL; typedef pair<int, int> PII; typedef pair<LL, LL> PLL; template <typename T> bool chkMax(T &x, T y) { return (y > x) ? x = y, 1 : 0; } template <typename T> bool chkMin(T &x, T y) { return (y < x) ? x = y, 1 : 0; } template <typename T> void inline read(T &x) { int f = 1; x = 0; char s = getchar(); while (s < '0' || s > '9') { if (s == '-') f = -1; s = getchar(); } while (s <= '9' && s >= '0') x = x * 10 + (s ^ 48), s = getchar(); x *= f; } const int N=5005; int n,a[N]; int f[N][N]; int main() { read(n); for(int i=1;i<=n;i++)read(a[i]); for(int i=1;i<=n;i++) for(int j=i+1;j<=n;j++)f[i][j]=2; sort(a+1,a+1+n); int res=n>=2?2:1; for(int i=1;i<=n;i++) { int L=i-1,R=i+1; while(L>=1&&R<=n) { if(a[R]-a[i]==a[i]-a[L]) { f[i][R]=max(f[i][R],f[L][i]+1); res=max(res,f[i][R]); L--; } else if(a[R]-a[i]>a[i]-a[L])L--; else R++; } } printf("%d",res); return 0; }

__EOF__

本文作者acwing_zyy
本文链接https://www.cnblogs.com/zyyun/p/16203325.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是博主的最大动力!
posted @   zyy2001  阅读(49)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!
点击右上角即可分享
微信分享提示